关于getDerivedStateFromProps填坑记录

 更新时间:2023年06月06日 16:32:33   作者:前端分享会  
这篇文章主要介绍了关于getDerivedStateFromProps填坑记录,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

项目场景

今天又来填一个坑!!!!

问题描述

最近写的react项目中用到getDerivedStateFromProps ,这可把我折腾坏了,先说说我想实现的目标吧,在一个组件中当它的props发生变化时,组件需要重新获取对应的数据刷新页面,一开始我想到的是getDerivedStateFromProps不是能监听到props的变化吗,

我就直接在这个函数中调用获取数据的方法,这里要注意getDerivedStateFromProps是静态方法不能用this直接调用组件中的方法,就想起上次看了一篇博客博主用的是new一个新的组件(下面会具体介绍),

让这个组件去调用组件中的方法,本来感觉有救了但是这又掉入另一个坑,如果只是想调用一些方法去实现简单的console.log(),这完全没问题,

但是想去修改这个组件的数据就有问题了,然后就绕过这个坑想想其他法子,最终通过一些自己都觉得复杂的过程实现了,但是对我来说这肯定不行,然后又去找了许多资料最后通过初始值和 key 值来实现 prop 改变 state ,

好了接下来好好介绍下。

前言

我们先来唠叨唠叨getDerivedStateFromProps的一些注意点

1、在用getDerivedStateFromProps时可能出现这样的问题

Can’t call setState on a component that is not yet mounted.

This is a no-op, but it might indicate a bug in your application. Instead, assign to this.state directly or define a state = {}; class property with the desired state in the *** component.

这是提示我们不能再一个组件尚未mounted时调用 setState() 方法,这是一个空操作,但是可能会导致bug,因为我们的getDerivedStateFromProps方法在mounted执行前会执行一次,但是在mounted执行完之前你是不能调用setState方法,但是可以通过return{}去修改state的值(这是这个方法的本质我就多不说了)

2、在这个方法中不能用this,因为这是个静态方法

3、出现死循环这是使用这个生命周期的一个常见 bug,我们来看的例子

Class ColorPicker extends React.Component {
    state = {
        color: '#000000'
    }
    static getDerivedStateFromProps (props, state) {
        if (props.color !== state.color) {
            return {
                color: props.color
            }
        }
        return null
    }
    ... // 选择颜色方法
    render () {
        .... // 显示颜色和选择颜色操作
    }
}

现在我们可以用这个颜色选择器来选择颜色,同时我们能传入一个颜色值并显示。

但是这个组件有一个 bug,我们传入一个颜色值后它能正确显示,但是再使用组件内部的选择颜色方法,我们会发现颜色不会变化,一直是传入的颜色值这是为什么呢?

我们联系下react执行更新的条件当组件的props或者state发生变化时,组件就会重新重新执行一遍更新的生命周期函数,在16^4中setState 和 forceUpdate就会触发更新,所以 return { color: props.color}后state会发生改变又会走 getDerivedStateFromProps 方法,并把 state 值更新为传入的 prop,我们来修理修理,加一个preColor去保存新的color如果上次的preColor和这次props中的color相同就不需要更新

Class ColorPicker extends React.Component {
    state = {
        color: '#000000',
        preColor: ''
    }
    static getDerivedStateFromProps (props, state) {
        if (props.color !== state.preColor) {
            return {
                color: props.color
                prevPropColor: props.color
            }
        }
        return null
    }
    ... // 选择颜色方法
    render () {
        .... // 显示颜色和选择颜色操作
    }
}

代码展示

下面进去我们的主题了,这是我的父组件,子组件通过子路由的形式放到父组件中

<div className={Css['goods-content']}>
    <Switch>
      <Route path={config.path+"goods/classify/items"} component={GoodsItems}></Route>
    </Switch>
</div>

这是我子组件中的getDerivedStateFromProps方法,我们先来看看通过new一个新的组建区调用函数(这里我不做上面第三个问题的bug处理了)这里我调用了一个打印函数 

  static getDerivedStateFromProps(newProps,preState)
    {
        new GoodsItems(newProps).console();
        return null;
    }
    console(){
        console.log("111")
    }

这里我们看到可以正确打印,但是我们现在城市去改变组件中的值

 this.state = {
      aGoods: [],
      cid:null,
      precid:null,
      num:1
}
        this.sum=0;
     static getDerivedStateFromProps(newProps,preState)
    {
        new GoodsItems(newProps).change();
        return null;
    }
   change(){
       this.setState({
           num:2
       },()=>{
           console.log("num1: ",this.state.num)
       })
       this.sum=this.sum+1;
       console.log("num2: ",this.state.num)
       console.log("sum: ",this.sum)
    }

我们可以看到num1没输出,每次num2都是1和sum都是1,这是因为每次都是new了一个新的组件改变的是新组建的值,并不影响原来的组件,所以不能用来改变state的值。

我不卖关子了直接上解决方案。

解决方案

我们将子组件直接放到父组件上,不使用子路由,然后给子组件加上一个key指,每次子组件需要更新时就将key值改变,这样的话就相当于重新加载了一个新的子组件而不是仅仅去更新数据

我们看代码:

<div className={Css['goods-content']}>
   <GoodsItems aGoods={this.state.aGoods ? this.state.aGoods: ''} key={this.state.cid}/>
</div>

这里我们也可以将数据传入,子组件在mounted时候进行setState修改数据

这是官网的解释

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • VSCode 配置React Native开发环境的方法

    VSCode 配置React Native开发环境的方法

    本篇文章主要介绍了VSCode 配置React Native开发环境的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • Vite搭建React项目的方法步骤

    Vite搭建React项目的方法步骤

    这篇文章主要介绍了Vite搭建React项目的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • react自定义实现状态管理详解

    react自定义实现状态管理详解

    这篇文章主要为大家详细介绍了react如何自定义实现状态管理,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • 在React页面重新加载时保留数据的实现方法总结

    在React页面重新加载时保留数据的实现方法总结

    在React页面重新加载时保留数据,可以通过多种方法来实现,常见的方法包括使用浏览器的本地存储(Local Storage 或 Session Storage)、URL参数、以及服务器端存储等,本文给大家总结了一些具体实现方法,需要的朋友可以参考下
    2024-06-06
  • React实现虚拟滚动的三种思路详解

    React实现虚拟滚动的三种思路详解

    在​​web​​开发的过程中,或多或少都会遇到大列表渲染的场景,为了解决大列表造成的渲染压力,便出现了虚拟滚动技术,本文主要介绍虚拟滚动的三种思路,希望对大家有所帮助
    2024-04-04
  • React-Router如何进行页面权限管理的方法

    React-Router如何进行页面权限管理的方法

    本篇文章主要介绍了React-Router如何进行页面权限管理的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • react中常见hook的使用方式

    react中常见hook的使用方式

    这篇文章主要介绍了react中常见hook的使用方式与区别,帮助大家更好的理解和学习使用react,感兴趣的朋友可以了解下
    2021-04-04
  • 详解使用webpack+electron+reactJs开发windows桌面应用

    详解使用webpack+electron+reactJs开发windows桌面应用

    这篇文章主要介绍了详解使用webpack+electron+reactJs开发windows桌面应用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-02-02
  • React  memo允许你的组件在 props 没有改变的情况下跳过重新渲染的问题记录

    React  memo允许你的组件在 props 没有改变的情况下跳过重新渲染的问题记录

    使用 memo 将组件包装起来,以获得该组件的一个 记忆化 版本,只要该组件的 props 没有改变,这个记忆化版本就不会在其父组件重新渲染时重新渲染,这篇文章主要介绍了React  memo允许你的组件在 props 没有改变的情况下跳过重新渲染,需要的朋友可以参考下
    2024-06-06
  • 在react中使用mockjs的方法你知道吗

    在react中使用mockjs的方法你知道吗

    这篇文章主要为大家详细介绍了在react中使用mockjs的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03

最新评论