// 组件即将挂载 componentWillMount() { // 初始化数据作用 console.log("componentWillMount") } // 堆代码 duidaima.com /* 在 16.2 之后版本使用会出现以下警告 ⚠️⚠️⚠️ react-dom.development.js:86 Warning: componentWillMount has been renamed, and is not recommended for use. See https://reactjs.org/link/unsafe-component-lifecycles for details. * Move code with side effects to componentDidMount, and set initial state in the constructor. * Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder. Please update the following components: App */ // 组件即将挂载 - 强制去掉警告,UNSAFE 提示开发者这是一个不安全的生命周期方法。 UNSAFE_componentWillMount() { // 初始化数据作用 console.log("componentWillMount") }componentWillMount 在16.2 之后官方不推荐使用了,这是因为 16.2 的时候 React 发生了一个改变,推出了几个新的生命周期,老的生命周期方法被替代掉了,不推荐使用。 那么为什么 React 要推出新的生命周期呢?
所以这个东西就是一个边缘化的问题,你的组件达到这样一个程度,它真的会出现假死的情况。所以 React Fiber 技术就是来优化了虚拟 Dom 的 diff 算法,它把创建 Dom 和组件渲染整个过程拆分成了无数个小的分片任务来执行。可以认为这个任务无比的碎片化,这个时候如果有优先级较高的任务就先执行优先级较高的任务。当优先级较低的任务在执行时候突然来了优先级较高的任务,这个时候会打断正在执行的低优先级任务,先执行优先级高的任务。
所谓的低优先级任务就是 componentWillMount 中去找哪些节点将要去挂载到页面中,而高优先级任务就是 render 正在渲染,didMount 挂载完成。这个时候我们低优先级的任务(找出那些需要更新的 Dom)这个过程是会被打断的,而我们更新 Dom 这个过程是不能被打断的,只能一鼓作气做完的,而 willMount 很不幸它是处在这个要找出来那些 Dom 是需要被更新的。所以这个过程是可以被打断的,所以可以认为 willMount 在忙着找出那些状态需要更新。因为接下来在 render 中就要开始更新了,didMount 就更新完成了。
这个时候 willMount 找是处于低优先级的,而这个时候 render 正在更新,因为碎片化任务,他可能还不是同步的。即某个组件可能处在在找那个状态需要更新,那个 Dom 需要更新,而那边组件已经到了 render 渲染部分了,这个时候就吧低优先级的任务给砍掉了。砍掉怎么办,会保存吗?不会。只能下次再来一遍,再来找那个节点需要更新。所以这个生命周期就可能会触发多次这样一个问题(失去了唯一性),所以这是一个有隐患的生命周期方法,所以这里不推荐使用。
componentDidMount() { // 数据请求axios // 订阅函数调用 // setInterval // 基于创建的完的dom进行初始化时候,例如 BetterScroll 使用 console.log("componentDidMount") }
// 组件即将更新 componentWillUpdate() { console.log("componentWillUpdate") } /* 在 16.2 之后版本使用会出现以下警告 ⚠️⚠️⚠️ react-dom.development.js:86 Warning: componentWillUpdate has been renamed, and is not recommended for use. See https://reactjs.org/link/unsafe-component-lifecycles for details. * Move data fetching code or side effects to componentDidUpdate. * Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder. Please update the following components: App */ // 组件即将更新 - 强制去掉警告,UNSAFE 提示开发者这是一个不安全的生命周期方法。 UNSAFE_componentWillUpdate() { console.log("componentWillUpdate") }2.2 render
// 组件更新完成 - 接收两个行参,老的属性、老的状态 componentDidUpdate(prevProps, prevState) { console.log(prevState) console.log("componentDidUpdate") }2.4 shouldComponentUpdate
// 组件是否应该更新?- 接受两个行参,新的属性、新的状态 shouldComponentUpdate(nextProps, nextState) { if (JSON.stringify(this.state) !== JSON.stringify(nextState)) { return true } else { return false } }
// 父组件修改属性触发,应用在子组件中才有意义 componentWillReceiveProps(nextProps) { // 最先获得父组件传来的属性,可以利用属性进行ajax或者逻辑处理 // 把属性转换为孩子的自己的状态等 }三. 销毁阶段
static getDerivedStateFromProps(nextProps, nextState) { console.log("getDerivedStateFromProps") return { } }4.2 getSnapshotBeforeUpdate
import React, { Component } from 'react' export default class App extends Component { state = { } // getDerivedStateFromProps 第一次的初始化组件以及后续的更新过程中(包括自身状态更新以及父传子),返回一个对象作为新的 state,返回 null 则说明不需要在这里更新 state // 这里不能做异步操作,因为这里 return 是立即返回的 static getDerivedStateFromProps(nextProps, nextState) { console.log("getDerivedStateFromProps") return { } } getSnapshotBeforeUpdate() { return 100 } componentDidUpdate(prevProps, prevState, value) { console.log(value) } render() { return ( <div> <button onClick={()=>{ this.setState({ }) }}>修改</button> </div> ) } }
class Greeting extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } }PureComponent 和 memo 仅作为性能优化的方式而存在。但请不要依赖它来“阻止”渲染,因为这会产生 bug。PureComponnet 和 memo 都是通过对 props 值的浅比较来决定该组件是否需要更新的。