• react新版本生命周期


    给componentWillMount componentWillReceiveProps componentWillUpdate生命周期加上UNSAFE_前缀,表明其不安全性,并将在未来版本将其移除

    官网文档指出使用这些生命周期的代码会在未来版本的react中更容易产生bug,尤其是对于异步渲染的版本
    新增生命周期static getDerivedStateFromProps(prevProps, prevState)、getSnapshotBeforeUpdate(prevProps, prevState) 、componendDidCatch(error, info)
    
    static getDerivedStateFromProps(prevProps, prevState) 在每次渲染之前都会调用,不管造成重新渲染的原因,不管初始挂载还是后面的更新都会调用,这一点和UNSAFE_componentWillReceiveProps不同(只有当父组件造成重新渲染时才调用),每次都应该返回一个对象作为state的更新,或者返回null表示不更新 它的使用场景一般为依赖于props的变化去做一些状态的更新,让我们能够根据props的变化去更新内部的状态,以前我们经常在componentWillReceiveProps中完成该操作 但是你需要考虑是否真的有必要使用这个生命周期,比如: 如果你需要根据网络请求获取数据,你可以在componentDidUpdate里完成 当props改变时,你需要去重新计算某些数据,可以使用memoization helper替代 当props改变时,如果你想要重置一些state,可以考虑使用Fully controlled component(完全移出state的使用,通过父组件控制数据)或者Fully uncontrolled component(数据仅存在内部状态中)
    getSnapshotBeforeUpdate(prevProps,prevState)
    在最新的渲染数据提交给DOM前会立即调用,它让你在组件的数据可能要改变之前获取他们,他的返回值会被传递给componentDidUpdate的第三个参数
    
    componentDidCatch
    如果一个组件定义了componentDidCatch生命周期,则他将成为一个错误边界(错误边界会捕捉渲染期间、在生命周期方法中和在它们之下整棵树的构造函数中的错误,就像使用了try catch,不会将错误直接抛出了,保证应用的可用性)


    class A extends React.Component {
      // 用于初始化 state
      constructor() {}
      // 用于替换 `componentWillReceiveProps` ,该函数会在初始化和 `update` 时被调用
      // 因为该函数是静态函数,所以取不到 `this`
      // 如果需要对比 `prevProps` 需要单独在 `state` 中维护
      static getDerivedStateFromProps(nextProps, prevState) {}
      // 判断是否需要更新组件,多用于组件性能优化
      shouldComponentUpdate(nextProps, nextState) {}
      // 组件挂载后调用
      // 可以在该函数中进行请求或者订阅
      componentDidMount() {}
      // 用于获得最新的 DOM 数据
      getSnapshotBeforeUpdate() {}
      // 组件即将销毁
      // 可以在此处移除订阅,定时器等等
      componentWillUnmount() {}
      // 组件销毁后调用
      componentDidUnMount() {}
      // 组件更新后调用
      componentDidUpdate() {}
      // 渲染组件函数
      render() {}
      // 以下函数不建议使用
      UNSAFE_componentWillMount() {}
      UNSAFE_componentWillUpdate(nextProps, nextState) {}
      UNSAFE_componentWillReceiveProps(nextProps) {}
    }
    
    

    getDerivedStateFromProps内部不可以有副作用,因为现在是无论是state改变还是props改变,

    都会执行它。

    例如:

    这种写法会导致多次循环渲染直到报错

    class App extends Component {
      constructor(props){
        super(props)
        this.myFetch=this.myFetch.bind(this)
        this.state = {
          name: "",
          list: null,
          myFetch:this.myFetch
        };
      }
    
    static getDerivedStateFromProps(props, state) {
        if ( props.name !== state.name ) {
          // 这一句是有副作用的,它会改变state状态,
          // 然后再次调用getDerivedStateFromProps,再次改变state状态...
          state.myFetch(props.name)
          return {
            name: props.name
          };
        }
        return null;
      }
      myFetch(){
          this.setState({
            list: "newList"
          })
      }
      render() {
        return (
          <div>{this.state.list}</div>
        );
      }
    }
    

    以上正确写法应为:

    class App extends Component {
      constructor(props){
        super(props)
        this.myFetch=this.myFetch.bind(this)
        this.state = {
          name: "",
          list: null,
          //myFetch:this.myFetch
        };
      }
    
      // 纯函数,无副作用
      static getDerivedStateFromProps(props, state) {
        if ( props.name !== state.name ) {
          return {
            name: props.name,
            list: null
          };
        }
        return null;
      }
      componentDidUpdate(){
        if(!this.state.list){
          this.myFetch(this.props.name)
        }
      }
    
      // 看是否需要初始化的时候调用
      componentDidMount(){
        this.myFetch(this.props.name)
      }
    
      myFetch(){
        this.setState({
          list: "newList"
        })
      }
      render() {
        return (
          <div>{this.state.list}</div>
        );
      }
    }
     
  • 相关阅读:
    String.trim()这个细节不能忘记
    Integer.parseInt(f.trim())中String f要加trim()
    类属性不能写在try{}catch(){}里面
    011--TypeScript泛型
    010--TypeScript里面的this和重载
    009--函数(基本实例和函数类型)
    007--TypeScript之类的修饰符
    008--TypeScript存储器和静态属性
    006--TypeScript之类
    005--TypeScript接口
  • 原文地址:https://www.cnblogs.com/xufeimei/p/9878418.html
Copyright © 2020-2023  润新知