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.memoopen in 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.forwardRefopen in 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>
    );
  }
}
上次更新:
Contributors: kyxiao