react生命周期,hooks对应的生命周期?
一、首先我们先看一下类(class)组件整个周期包含哪些:
class MyComponent extends Component { // ======= 挂载卸载阶段 constructor(props: any) { super(props); this.state = { name: 'Hello World', }; } // 16.8 新增钩子函数 static getDerivedStateFromProps(props, state) { console.log('判断数据是否需要更新', props, state); return null; } // 16.8 已废弃 componentWillMount() { console.log('渲染之前'); } // 16.8 componentWillMount变更,后续可能会废弃 UNSAFE_componentWillMount() { console.log('渲染之前'); } render() { console.log('渲染'); return <div>MyComponent</div>; } componentDidMount() { console.log('渲染完成'); } // ==========更新阶段,也会重新调用getDerivedStateFromProps // 16.8 新增钩子函数 static getDerivedStateFromProps(props, state) { console.log('判断数据是否需要更新', props, state); return null; } // 16.8已废弃 componentWillReceiveProps(nextProps) { console.log('接收到来自父组件的数据', nextProps); } // 16.8 componentWillReceiveProps变更而来 UNSAFE_componentWillReceiveProps(nextProps) { console.log('接收到来自父组件的数据', nextProps); } // 16.8新增钩子函数 static getSnapshotBeforeUpdate(prevProps, prevState) { console.log('返回组件更新daom', prevProps, prevState); } shouldComponentUpdate(nextProps, nextState) { console.log('判断数据是否更新true,false来判断', nextProps, nextState); return false; } // 16.8已废弃 componentWillUpdate(nextProps, nextState) { console.log('组件数据将要更新', nextProps, nextState); } // 16.8 变更componentWillUpdate UNSAFE_componentWillUpdate(nextProps, nextState) { console.log('组件数据将要更新', nextProps, nextState); } componentDidUpdate(prevProps) { console.log('组件数据更新完毕', prevProps); } // ========= 卸载阶段 componentWillUnmount() { console.log('已经销毁'); } // 其他api static getDerivedStateFromError(error) { // 更新 state 使下一次渲染可以显示降级 UI return { hasError: true }; } componentDidCatch(error, info) { // 捕获错误信息 } // 增加错误信息校验 render() { if (this.state.hasError) { // 你可以渲染任何自定义的降级 UI return <h1>Something went wrong.</h1>; } return this.props.children; } }
1、constructor:
构造函数,如不初始化state或者进行函数绑定,可以不进行react组件实现构造函数;通过在构造函数中初始化state,接受来自父组件的props
2、getDerivedStateFromProps:
16.8之后的一个静态方法,通过接受父组件props判断是否执行更新,返回null不更新,具体见另外一篇文章分析,详见react16.8 新的生命周期
3、componentWillMount(已过时) => UNSAFE_compomentWillMount
react 16.8之前的周期函数,在render之前调用,所有setState不会出来额外渲染,组件dom节点没有渲染之前进行加载一些数据,一般进行服务端渲染的时候进行优化,16.8以后改为UNSAFE_compomentWillMount,但是没有被废弃,保留原来的函数;
4、render:
一个纯渲染函数,返回Dom,React组件,Fragment等
5、componentDidMount:
组件挂载时调用,此时dom已渲染,可以获取canvas,svg等操作,可以进行数据操作,获取接口数据;
6、componentWillReceiveProps(已过时) => UNSAFE_componentWillReceiveProps
组件挂载阶段接受父组件props参数进行state更新操作,需要妥善处理,不然容易循环渲染等问题,16.8以后被getDerivedStateFromProps替换;
7、getSnapshotBeforeUpdate:
16.8以后的一个静态方法,判断dom节点更新阶段更新时,及时获取更新后的dom节点,同样进行单独的分析,详见 react16.8 新的生命周期
8、shouldComponentUpdate:
一个比较重要的周期,在组件更新阶段是否执行更新操作,默认返回false不重新渲染,返回true重新渲染,根据props和state的进行比较是否进行节点更新操作,component和pureComponent区别就在于此
9、componentWillUpdate (已过时)=> UNSAFE_compinetWillUpdate
16.8已废弃,更新阶段获取更新后的dom节点,为更新阶段做准备;
10、componentDidUpdate:
组件更新阶根据返回的参数props,state,snapshot,第三个参数是之前getSnapshotBeforeUpdate返回的,如果出来函数毁掉时需要Dom元素的状态,则将对比计算机的过程迁移至getSanapShotBeforeUpdate,然后在componentDidUpdate中统一触发更新;
11、componentWillUnmount:
我们组件卸载阶段执行的方法,组件销毁进行执行初始化的一些操作;
12、getDeriedStateFromError和componentDidCatch
错误捕获日志,我们可以根据我们错误信息进行捕获,增加错误边界等组件进行1前端代码兼容
二、然后我们再看看无状态(hooks)组件的钩子函数
const MyComponent = React.memo((props) =>{
React.useMemo(() => ()=>{ console.log('组件dom节点没有渲染之前调用一次'); }, []); const renderDom = React.useMemo(() => ()=>{ console.log('组件dom节点没有渲染之前根据依赖参数props调用'); }, [props]) React.useEffect(() => { console.log('组件初始化调用一次'); }, []) React.useEffect(()=>{ console.log('组件根据依赖参数props更新调用'); },[props]) React.useEffect(()=>{ return ()=>{ console.log('组件卸载调用'); } },[]); const handleClick = React.useCallback(() =>{ console.log('监听事件通过钩子函数包裹,优化性能'); },[]); return ( console.log('返回dom节点'); ) });
1、useState:
和class的state类似,只不过是独立管理组件变量,
2、useMemo:
组件Dom节点,进行计算一些,包括要渲染的Dom或者数据,根据依赖参数进行更新
3、useEffect:
hooks的组件生命周期其实就是钩子函数useEffect的不同用法,传递参数的不同会导致不同的结果,具体分析见React.useEffect参数不同
4、useCallBack:
一个钩子函数,通过包裹我们的普通函数进行性能优化;
后面继续完善