# React API

序号 分类 API 描述
1 组件类 Component
2 PureComponent 纯函数
3 memo 纯函数
4 forwardRef 用于 隔代 ref 获取引用
5 lazy 结合 Suspense 实现动态(异步)加载组件
6 Suspense Suspense 让组件“等待”某个异步操作(数据、组件、图片、脚本等),直到该异步操作结束即可渲染。
7 Fragment 碎片概念,用于 React 返回多个元素。默认 react 是不允许返回多个元素节点的,即一个根元素。
8 Profiler 一般用于开发阶段,性能检测,检测一次 react 组件渲染用时,性能开销。
9 StrictMode 严格模式,用于检测react项目中的潜在的问题。严格模式检查仅在开发模式下运行;它们不会影响生产构建。
10 工具类 createElement 创建 React 元素。每个 JSX 元素都是调用 React.createElement() 的语法糖。
11 cloneElement 克隆 React 元素。
12 createContext 可用于层层传递 value
13 createFactory(已废弃) 此辅助函数已废弃,建议使用 JSX 或直接调用 React.createElement() 来替代它。
14 createRef createRef 可以创建一个 ref 元素,附加在 react 元素上。
15 isValidElement 验证对象是否为 React 元素,返回值为 truefalse。适用于公共组件或是开源库。
16 Children 提供了用于处理 this.props.children 不透明数据结构的实用方法。
17 Hooks useState 返回一个 state,以及更新 state 的函数。
18 useEffect 可以用作数据交互,或是生命周期。
19 useLayoutEffect 同 useEffect。
20 useMemo useMemo 接受两个参数,第一个参数是一个函数,返回值用于产生保存值。
21 useCallback 返回一个 memoized 回调函数。
22 useRef 可以用来获取 dom 元素,或者 class 组件实例。或保存一些数据
23 useReducer useState 的替代方案。
24 useContext useContext 可以代替 context.Consumer 来获取 Provider 中保存的 value 值。
25 useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值。
26 useDebugValue useDebugValue 可用于在 React 开发者工具中显示自定义 hook 的标签。
27 useTransition 允许延时由 state 改变而带来的视图渲染。这个 api 目前处于实验阶段,没有被完全开放出来。
28 ReactDOM render 用于渲染一个 react 元素,一般 react 项目我们都用它,渲染根部容器 app
29 hydrate 服务端渲染用 hydrate。用法与 render() 相同
30 createPortal Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案。例如弹窗
31 unstable_batchedUpdates 批量更新
32 flushSync 可以将回调函数中的更新任务,放在一个较高的优先级中。
33 findDOMNode 用于访问组件DOM元素节点,不推荐
34 unmountComponentAtNode DOM 中卸载组件,会将其事件处理器和 state 一并清除。

# 组件类

# Component

# PureComponent

纯组件:浅比较 propsstate,用于 性能优化,减少 render 次数

使用场景:data中只有一层基本类型数据

# memo

React.memo (opens new window)为高阶组件,用于 性能优化。仅对 props 进行浅比较,当 state 或 context 发生变化时,它仍会重新渲染。如果想控制对复杂对象,可以通过传入第二个参数实现。

React.memo: 第二个参数 返回 true 组件不渲染 , 返回 false 组件重新渲染。

shouldComponentUpdate: 返回 true 组件渲染 , 返回 false 组件不渲染。

import React, { useState } from "react";

// 子组件
const TextDemo = (props) => {
  return <div>number: {props.number}</div>;
};
const NewTextDemo = React.memo(TextDemo, (prev, next) => {
  if (next.number === prev.number) return true; // 数据相同时,不渲染
  if (next.number > 5) return true; // 数据大于5时,不渲染
  return false; // 否则,渲染组件
});

// 父组件
const Memo = () => {
  const [number, setNumber] = useState(0);

  return (
    <>
      <NewTextDemo number={number} />
      <button onClick={() => setNumber(number + 1)}>number++</button>
      <button onClick={() => setNumber(number - 1)}>number--</button>
    </>
  );
};
export default Memo;

# forwardRef

用于 隔代 ref 获取引用

# 1. 转发refs到DOM组件

import React, { useEffect, useRef } from "react";

// 孙组件
const Son = (props) => {
  const { grandRef } = props;
  return <div ref={grandRef}>这个是想要获取的元素</div>;
};

// 父组件
const Father = (props) => {
  return (
    <div>
      <Son grandRef={props.grandRef} />
    </div>
  );
};
const NewFather = React.forwardRef((props, ref) => (
  <Father grandRef={ref} {...props} />
));

// 爷组件
const GrandFather = (props) => {
  const ref = useRef();
  useEffect(() => {
    console.log(ref.current);
  }, []);
  return <NewFather ref={ref} />;
};

export default GrandFather;

# 高阶组件转发refs

React.forwardRef (opens new window)

import React, { useRef, useEffect } from "react";

// 高阶组件
const HOC = (Component) => {
  class Wrap extends React.Component {
    render() {
      const { forwardedRef, ...otherprops } = this.props;
      return <Component ref={forwardedRef} {...otherprops} />;
    }
  }
  return React.forwardRef((props, ref) => (
    <Wrap forwardedRef={ref} {...props} />
  ));
};

// 子组件 - 使用高阶组件
class Child extends React.Component {
  componentDidMount() {
    console.log(666);
  }
  render() {
    return <div>hello,world</div>;
  }
}
const HocChild = HOC(Child, true);

// 父组件
const ForwardRefHOC = () => {
  const node = useRef(null);
  useEffect(() => {
    /* 就可以跨层级,捕获到 Child 组件的实例了 */
    console.log(node.current.componentDidMount);
  }, []);
  return <HocChild ref={node} />;
};
export default ForwardRefHOC;

# lazy

结合 Suspense 实现动态(异步)加载组件

import React from "react";

// 子组件
const Test = () => (
  <img src="https://picsum.photos/id/6/300/200" alt="img" />
);

// 父组件
const LazyComponent = React.lazy(
  () =>
    new Promise((resolve) => {
      setTimeout(() => {
        resolve({
          default: () => <Test />
        });
      }, 2000);
    })
);

// 调用
class Lazy extends React.Component {
  render() {
    return (
      <div className="context_box" style={{ marginTop: "50px" }}>
        <React.Suspense fallback={<div>Loading...</div>}>
          <LazyComponent />
        </React.Suspense>
      </div>
    );
  }
}
export default Lazy;

# Suspense

Suspense 让组件“等待”某个异步操作(数据、组件、图片、脚本等),直到该异步操作结束即可渲染。

import React from "react";

// 该组件是动态加载的
const OtherComponent = React.lazy(() => import("./Lazy"));

const Suspense = () => {
  return (
    // 显示 <Spinner> 组件直至 OtherComponent 加载完成
    <React.Suspense fallback={<div>Suspense Loading...</div>}>
      <OtherComponent />
    </React.Suspense>
  );
};

export default Suspense;

# Fragment

碎片概念,用于 React 返回多个元素。默认 react 是不允许返回多个元素节点的,即一个根元素。

Fragment 可以支持 key 属性。<></> 不支持 key 属性。

温馨提示:我们通过 map 遍历后的元素,react 底层会处理,默认在外部嵌套一个 <Fragment>

import React from 'react';

export default () => {
  return (
    <React.Fragment>
      <li> 🍎🍎🍎 </li>
      <li> 🍌🍌🍌 </li>
      <li> 🍇🍇🍇 </li>
    </React.Fragment>
  )
}
import React from 'react';

export default () => {
  return (
    <>
      <li> 🍎🍎🍎 </li>
      <li> 🍌🍌🍌 </li>
      <li> 🍇🍇🍇 </li>
    </>
  )
}

# Profiler

一般用于开发阶段,性能检测,检测一次 react 组件渲染用时,性能开销。

import React, { useEffect, useState } from "react";

const Profiler = () => {
  const [number, setNumber] = useState(0);
  useEffect(() => {
    setTimeout(() => {
      setNumber(1);
    }, 2000);
  }, []);
  const callback = (...arg) => {
    console.log(arg);
  };

  return (
    <React.Profiler id="ProfilerTest" onRender={callback}>
      <div>{number}</div>
    </React.Profiler>
  );
};

export default Profiler;

# StrictMode

严格模式,用于检测react项目中的潜在的问题。严格模式检查仅在开发模式下运行;它们不会影响生产构建。

StrictMode目前有助于:

  • ①识别不安全的生命周期。
  • ②关于使用过时字符串 ref API 的警告
  • ③关于使用废弃的 findDOMNode 方法的警告
  • ④检测意外的副作用
  • ⑤检测过时的 context API

# 工具类

# createElement

创建 React 元素。每个 JSX 元素都是调用 React.createElement() 的语法糖。

React.createElement(
  type,
  [props],
  [...children]
)
import React from "react";

const CreateElement = () => {
  return React.createElement(
    "div",
    { className: "parent" },
    React.createElement(
      "div",
      { className: "item" },
      "\u751F\u547D\u5468\u671F"
    ),
    React.createElement(React.Fragment, null, " Flagment"),
    "text\u6587\u672C"
  );
};
export default CreateElement;

# cloneElement

克隆 React 元素。

import React from "react";

const FatherComponent = ({ children }) => {
  const newChildren = React.cloneElement(children, { age: 18 });
  return <div> {newChildren} </div>;
};

const SonComponent = (props) => {
  console.log(props);
  return <div>hello,world</div>;
};

const CloneElement = () => {
  return (
    <div className="box">
      <FatherComponent>
        <SonComponent name="alien" />
      </FatherComponent>
    </div>
  );
};

export default CloneElement;

# createContext

可用于层层传递 value

只有当组件所处的树中没有匹配到 Provider 时,其 defaultValue 参数才会生效。

import React from "react";

const defaultValue = { name: "xiaoli", mes: "默认值" };
const MyContext = React.createContext(defaultValue);

const ComponentA = (props) => {
  const { name, mes } = props;
  return (
    <div>
      <div> 姓名: {name} </div>
      <div> 想对大家说: {mes} </div>
    </div>
  );
};

const ComponentB = () => {
  /* 用 Consumer 订阅, 来自 Provider 中 value 的改变  */
  return (
    <MyContext.Consumer>
      {(value) => <ComponentA {...value} />}
    </MyContext.Consumer>
  );
};

const CreateContext = () => {
  const [value] = React.useState({
    name: "alien",
    mes: "let us learn React "
  });
  return (
    <div style={{ marginTop: "50px" }}>
      <MyContext.Provider value={value}>
        <ComponentB />
      </MyContext.Provider>
    </div>
  );
};

export default CreateContext;

# createFactory(已废弃)

此辅助函数已废弃,建议使用 JSX 或直接调用 React.createElement() 来替代它。

const Text = React.createFactory(()=><div>hello,world</div>) 
const Index = () => {  
  return <div style={{ marginTop:'50px'  }} >
    <Text/>
  </div>
}

# createRef

createRef 可以创建一个 ref 元素,附加在 react 元素上。

class Index extends React.Component{
  constructor(props){
    super(props)
    this.node = React.createRef()
  }
  componentDidMount(){
    console.log(this.node)
  }
  render(){
    return <div ref={this.node} > my name is alien </div>
  }
}

也可以不用,替代写法

class Index extends React.Component{
  node = null
  componentDidMount(){
    console.log(this.node)
  }
  render(){
    return <div ref={(node)=> this.node } > my name is alien </div>
  }
}

或者函数组件中

function Index(){
  const node = React.useRef(null)
  useEffect(()=>{
      console.log(node.current)
  },[])
  return <div ref={node} >  my name is alien </div>
}

# isValidElement

验证对象是否为 React 元素,返回值为 truefalse。适用于公共组件或是开源库。

场景:验证容器组件的所有子组件,过滤到非react element类型。

const Text = () => <div>hello,world</div> 
class WarpComponent extends React.Component{
    constructor(props){
      super(props)
    }
    render(){
      return this.props.children.filter(item => React.isValidElement(item) ); // 过滤掉了最后一行纯文本
    }
}
function Index(){
  return <div style={{ marginTop:'50px' }} >
    <WarpComponent>
      <Text/>
      <div> my name is alien </div>
      Let's learn react together!
    </WarpComponent>
  </div>
}

# Children

提供了用于处理 this.props.children 不透明数据结构的实用方法。

# map

遍历 children,并返回新数组。

class Text extends React.Component{
    render(){
        return <div>hello,world</div>
    }
}

function WarpComponent(props){
    const newChildren = React.Children.map(props.children,(item)=>item)
    console.log(newChildren)
    return newChildren
} 

function Index(){
    return <div style={{ marginTop:'50px' }} >
        <WarpComponent>
            { new Array(3).fill(0).map(()=><Text/>) }
            <span>hello,world</span>
        </WarpComponent>
    </div>
}

# forEach

仅遍历 children

function WarpComponent(props){
    React.Children.forEach(props.children,(item)=>console.log(item))
    return props.children
}   

# count

Children.count 可以返回同一级别子组件的数量。

function WarpComponent(props){
    const childrenCount =  React.Children.count(props.children)
    console.log('childrenCount: ', childrenCount); // childrenCount: 7
    return props.children
}   
function Index(){
    return <div style={{ marginTop:'50px' }} >
        <WarpComponent>
            { new Array(3).fill(0).map((item,index) => new Array(2).fill(1).map((item,index1) => <Text key={index+index1} />)) }
            <span>hello,world</span>
        </WarpComponent>
    </div>
}

# toArray

Children.toArray 返回,props.children 扁平化后结果。

React.Children.toArray() 在拉平展开子节点列表时,更改 key 值以保留嵌套数组的语义。

# only

验证 children 是否只有一个子节点(一个 React 元素),如果有则返回它,否则此方法会抛出错误。

# Hooks

# useState

返回一个 state,以及更新 state 的函数。

const [state, setState] = useState(initialState);

setState(newState);

# useEffect

可以用作数据交互,或是生命周期。

默认情况下,effect 将在每轮渲染结束后执行,但你可以选择让它 在只有某些值改变的时候(传入第二个依赖数组参数) 才执行。

useEffect(() => {
  const subscription = props.source.subscribe();
  return () => {
    // 清除订阅
    subscription.unsubscribe();
  };
}, [props]);

# useMemo

useMemo 接受两个参数,第一个参数是一个函数,返回值用于产生保存值。 第二个参数是一个数组,作为dep依赖项,数组里面的依赖项发生变化,重新执行第一个函数,产生新的值。

应用场景:

  1. 缓存一些值,避免重新执行上下文
const number = useMemo(()=>{
    /** ....大量的逻辑运算 **/
   return number
},[ props.number ]) // 只有 props.number 改变的时候,重新计算number的值。
  1. 减少不必要的dom循环
/* 用 useMemo包裹的list可以限定当且仅当list改变的时候才更新此list,这样就可以避免selectList重新循环 */
 {
   useMemo(() => (
    selectList.map((i, v) => (
      <span className={style.listSpan} key={v} >
        {i.patentName} 
      </span>
    ))
  ), [selectList])
 }
  1. 减少子组件渲染
/* 只有当props中,list列表改变的时候,子组件才渲染 */
const  goodListChild = useMemo(()=> <GoodList list={ props.list } /> ,[ props.list ])

# useCallback

返回一个 memoized 回调函数。区别:useMemo 返回的是函数运行的结果, useCallback 返回的是函数。

/* 用react.memo */
const DemoChildren = React.memo((props) => {
  /* 只有初始化的时候打印了 子组件更新 */
  console.log("子组件更新");
  useEffect(() => {
    props.getInfo("子组件");
  }, []);
  return <div>子组件</div>;
});
const DemoUseCallback = ({ id }) => {
  const [number, setNumber] = useState(1);
  /* 此时usecallback的第一参数 (sonName)=>{ console.log(sonName) } 经过处理赋值给 getInfo */
  const getInfo = useCallback(
    (sonName) => {
      console.log(sonName);
    },
    [id]
  );
  return (
    <div>
      {/* 点击按钮触发父组件更新 ,但是子组件没有更新 */}
      <button onClick={() => setNumber(number + 1)}>增加</button>
      <DemoChildren getInfo={getInfo} />
    </div>
  );
};

# useRef

useRef的作用:

  1. 是可以用来获取 dom 元素,或者 class 组件实例。
  2. 创建 useRef 时候,会创建一个原始对象,只要函数组件不被销毁,原始对象就会一直存在,那么我们可以利用这个特性,来通过 useRef 保存一些数据。
const DemoUseRef = () => {
  const dom = useRef(null);
  const handerSubmit = () => {
    /*  <div >表单组件</div>  dom 节点 */
    console.log(dom.current);
  };
  return (
    <div>
      {/* ref 标记当前dom节点 */}
      <div ref={dom}>表单组件</div>
      <button onClick={() => handerSubmit()}>提交</button>
    </div>
  );
};

# useLayoutEffect

同 useEffect。执行顺序不同:组件更新挂载完成 -> 执行 useLayoutEffect 回调-> 浏览器dom绘制完成。可能会阻塞浏览器的绘制

# useReducer

useState 的替代方案。使用场景:state 逻辑较复杂且包含多个子值,或者下一个 state 依赖于之前的 state 等。

const [state, dispatch] = useReducer(reducer, initialState, init);
const DemoUseReducer = () => {
  /* number为更新后的state值,  dispatchNumbner 为当前的派发函数 */
  const [number, dispatchNumbner] = useReducer((state, action) => {
    const { payload, name } = action;
    /* return的值为新的state */
    switch (name) {
      case "add":
        return state + 1;
      case "sub":
        return state - 1;
      case "reset":
        return payload;
    }
    return state;
  }, 0);
  return (
    <div>
      当前值:{number}
      {/* 派发更新 */}
      <button onClick={() => dispatchNumbner({ name: "add" })}>增加</button>
      <button onClick={() => dispatchNumbner({ name: "sub" })}>减少</button>
      <button onClick={() => dispatchNumbner({ name: "reset", payload: 666 })}>
        赋值
      </button>
      {/* 把dispatch 和 state 传递给子组件  */}
      <MyChildren dispatch={dispatchNumbner} State={{ number }} />
    </div>
  );
};

# useContext

useContext 可以代替 context.Consumer 来获取 Provider 中保存的 value 值。

/* 用useContext方式 */
const DemoContext = () => {
  const value: any = useContext(Context);
  /* my name is alien */
  return <div> my name is {value.name}</div>;
};
/* 用Context.Consumer 方式 */
const DemoContext1 = () => {
  return (
    <Context.Consumer>
      {/*  my name is alien  */}
      {(value) => <div> my name is {value.name}</div>}
    </Context.Consumer>
  );
};

export default () => {
  return (
    <div>
      <Context.Provider value={{ name: "alien", age: 18 }}>
        <DemoContext />
        <DemoContext1 />
      </Context.Provider>
    </div>
  );
};

# useImperativeHandle

useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值。useImperativeHandle 应当与 forwardRef 一起使用,实现父组件操作子组件。

import React, {
  useState,
  useRef,
  useImperativeHandle,
  forwardRef
} from "react";

const FancyInput = (props, ref) => {
  const [inputValue, setInputValue] = useState("");
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
    changeValue: (value) => {
      setInputValue(value);
    }
  }));
  const handleChange = (e) => {
    setInputValue(e.target.value);
  };
  return <input ref={inputRef} value={inputValue} onChange={handleChange} />;
};
const FancyInputDemo = forwardRef(FancyInput);

const UseImperativeHandle = () => {
  const inputRef = useRef();
  const handerClick = () => {
    const { focus, changeValue } = inputRef.current;
    focus();
    changeValue(2222);
  };
  return (
    <>
      <FancyInputDemo ref={inputRef} />
      <button onClick={handerClick}>操控子组件</button>
    </>
  );
};

export default UseImperativeHandle;

# useDebugValue

useDebugValue 可用于在 React 开发者工具中显示自定义 hook 的标签。

==提示:我们不推荐你向每个自定义 Hook 添加 debug 值。当它作为共享库的一部分时才最有价值。==

function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);
  // ...
  // 在开发者工具中的这个 Hook 旁边显示标签
  // e.g. "FriendStatus: Online"
  useDebugValue(isOnline ? 'Online' : 'Offline');

  return isOnline;
}

# useTransition

useTransition 允许延时由 state 改变而带来的视图渲染。这个 api 目前处于实验阶段,没有被完全开放出来。

const SUSPENSE_CONFIG = { timeoutMs: 2000 };

function App() {
  const [resource, setResource] = useState(initialResource);
  const [startTransition, isPending] = useTransition(SUSPENSE_CONFIG);
  return (
    <>
      <button
        disabled={isPending}
        onClick={() => {
          startTransition(() => {
            const nextUserId = getNextId(resource.userId);
            setResource(fetchProfileData(nextUserId));
          });
        }}
      >
        Next
      </button>
      {isPending ? " 加载中..." : null}
      <Suspense fallback={<Spinner />}>
        <ProfilePage resource={resource} />
      </Suspense>
    </>
  );
}

# ReactDOM

# render

用于渲染一个 react 元素,一般 react 项目我们都用它,渲染根部容器 app

import ReactDOM from "react-dom";
ReactDOM.render(< App / >, document.getElementById('app'));

# hydrate

服务端渲染用 hydrate。用法与 render() 相同,但它用于在 ReactDOMServer 渲染的容器中对 HTML 的内容进行 hydrate 操作。

ReactDOM.hydrate(element, container[, callback])

# createPortal

Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案。例如弹窗

接受两个参数,第一个: child 是任何可渲染的 React 子元素 第二个: container是一个 DOM 元素。

ReactDOM.createPortal(child, container)
function WrapComponent({ children }) {
  const domRef = useRef(null);
  const [PortalComponent, setPortalComponent] = useState(null);
  React.useEffect(() => {
    setPortalComponent(ReactDOM.createPortal(children, domRef.current));
  }, []);
  return (
    <div>
      <div className="container" ref={domRef}></div>
      {PortalComponent}
    </div>
  );
}

class Index extends React.Component {
  render() {
    return (
      <div style={{ marginTop: "50px" }}>
        <WrapComponent>
          <div>hello,world</div>
        </WrapComponent>
      </div>
    );
  }
}

# unstable_batchedUpdates

react-legacy 模式下,对于事件,react 事件有批量更新来处理功能,但是在一些非常规的事件中,批量更新功能会被打破。可以用 unstable_batchedUpdates 解决。

class Index extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      numer: 1
    };
  }
  handerClick = () => {
    Promise.resolve().then(() => {
      ReactDOM.unstable_batchedUpdates(() => {
        this.setState({ numer: this.state.numer + 1 });
        console.log(this.state.numer);
        this.setState({ numer: this.state.numer + 1 });
        console.log(this.state.numer);
        this.setState({ numer: this.state.numer + 1 });
        console.log(this.state.numer);
      });
    });
  };
  render() {
    return (
      <div style={{ marginTop: "50px" }}>
        <button onClick={this.handerClick}>click me</button>
      </div>
    );
  }
}

# flushSync

flushSync 可以将回调函数中的更新任务,放在一个较高的优先级中。

import ReactDOM from "react-dom";
class Index extends React.Component {
  state = { number: 0 };
  handerClick = () => {
    setTimeout(() => {
      this.setState({ number: 1 });
    });
    this.setState({ number: 2 });
    ReactDOM.flushSync(() => {
      this.setState({ number: 3 });
    });
    this.setState({ number: 4 });
  };
  render() {
    const { number } = this.state;
    console.log(number); // 打印什么?? - 0 3 4 1
    return (
      <div>
        <div>{number}</div>
        <button onClick={this.handerClick}>测试flushSync</button>
      </div>
    );
  }
}

# findDOMNode

findDOMNode 用于访问组件DOM元素节点,react 推荐使用 ref 模式,不期望使用findDOMNode。且 不能用于函数组件

class Index extends React.Component {
  handerFindDom = () => {
    console.log(ReactDOM.findDOMNode(this));
  };
  render() {
    return (
      <div style={{ marginTop: "100px" }}>
        <div>hello,world</div>
        <button onClick={this.handerFindDom}>获取容器dom</button>
      </div>
    );
  }
}

# unmountComponentAtNode

DOM 中卸载组件,会将其事件处理器和 state 一并清除。

function Text() {
  return <div>hello,world</div>;
}

class Index extends React.Component {
  node = null;
  constructor(props) {
    super(props);
    this.state = {
      numer: 1
    };
  }
  componentDidMount() {
    /*  组件初始化的时候,创建一个 container 容器 */
    ReactDOM.render(<Text />, this.node);
  }
  handerClick = () => {
    /* 点击卸载容器 */

    const state = ReactDOM.unmountComponentAtNode(this.node);
    console.log(state);
  };
  render() {
    return (
      <div style={{ marginTop: "50px" }}>
        <div ref={(node) => (this.node = node)}></div>
        <button onClick={this.handerClick}>click me</button>
      </div>
    );
  }
}
更新时间: 3/25/2022, 7:13:26 PM