首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >componentWillReceiveProps对getDerivedStateFromProps

componentWillReceiveProps对getDerivedStateFromProps
EN

Stack Overflow用户
提问于 2018-08-03 11:26:08
回答 3查看 6.9K关注 0票数 11

对我来说,componentWillReceiveProps和getDerivedStateFromProps到底是个微妙的问题。因为,我在使用getDerivedStateFromProps时遇到了一个问题:

代码语言:javascript
复制
// Component 
state = {
  myState: []
}

// Using this method works fine:

componentWillReceiveProps(nextProps) {
  this.setState({
    myState: nextProps.myPropsState
  })
}

// But using this method will cause the checkboxes to be readonly:

static getDerivedStateFromProps(nextProps,prevProps) {
  const { myPropsState: myState } = nextProps
  return {
    myState
  }
}

// And here's checkbox
<input type="checkbox" id={`someid`} 
 onChange={(e) => this.handleMethod(e, comp.myState)} 
 checked={myState.indexOf(comp.myState) > -1} />

React版本: 16.4.1

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-08-04 14:09:54

最后,我解决了我的问题。这是一次痛苦的调试:

代码语言:javascript
复制
// Child Component

// instead of this
// this.props.onMyDisptach([...myPropsState])

// dispatching true value since myPropsState contains only numbers
this.props.onMyDispatch([...myPropsState, true])

这是因为,我有两个条件: 1)在复选框上更改(组件) 2)在重置按钮上按下(子组件)

当按下重置按钮时,我需要重新设置状态。因此,在将状态分配到道具以进行重置按钮时,我使用了一个布尔值来知道这是对重置的更改。你可以使用任何你喜欢的,但需要跟踪。

现在,在组件中,我在调试控制台输出后发现了一些提示,说明了componentWillReceiveProps和getDerivedStateFromProps之间的差异。

代码语言:javascript
复制
// Component
static getDerivedStateFromProps(props, state) {
    const { myPropsState: myState } = props
    // if reset button is pressed
    const true_myState = myState.some(id=>id===true)
    // need to remove true value in the store
    const filtered_myState = myState.filter(id=>id!==true)
    if(true_myState) {
      // we need to dispatch the changes to apply on its child component
      // before we return the correct state
      props.onMyDispatch([...filtered_myState])
      return {
        myState: filtered_myState
      }
    }
    // obviously, we need to return null if no condition matches
    return null
  }

--下面是我发现的控制台输出的结果:

  • 每当道具更改时,getDerivedStateFromProps立即记录
  • 只有在子程序传播道具更改后,componentWillReceiveProps才会记录
  • getDerivedStateFromProps不响应道具更改(我指的是调度更改,如示例代码所示)
  • componentWillReceiveProps响应道具的更改
  • 因此,我们需要在使用getDerivedStateFromProps时向子组件提供更改。

在我需要的状态下粘贴真值的过程,因为getDerivedStateFromProps处理所有的更改,不像componentWillReceiveProps只处理子组件,而是将更改分派给道具。

顺便说一句,您可以使用自定义属性来检查它是否被更改,并更新值(如果是getDerivedStateFromProps ),但是由于某些原因,我不得不修改这种技术。

我的措辞可能有些混乱,但我希望你能明白。

票数 1
EN

Stack Overflow用户

发布于 2018-08-03 11:35:02

getDerivedStateFromProps并不是componentWillReceiveProps的直接替代品,这完全是因为在每次更新之后调用它,无论是状态的更改、道具的更改还是父级的重新呈现。

无论如何,简单地从getDerivedStateFromProps 返回状态并不是正确的方法,您需要在返回值之前对状态和道具进行比较。否则,每更新一次,状态就会被重置为支持,并且循环将继续

根据文档

在调用render方法之前,在初始挂载和后续更新中都会调用getDerivedStateFromProps。它应该返回一个对象来更新状态,或者null返回什么都不更新。 此方法存在于一些罕见的用例中,在这种情况下,状态依赖于随时间而变化的道具。例如,可以方便地实现一个<Transition>组件,该组件比较它以前的子组件和下一个子组件,以决定它们中的哪一个要进入和输出。 派生状态会导致冗长的代码,使您的组件难以考虑。确保您熟悉更简单的替代方案: 如果您需要执行副作用(例如,数据获取或动画)以响应道具的更改,则使用componentDidUpdate生命周期。 如果您只想在道具更改时才重新计算某些数据,请使用memoization助手。 如果您想在道具更改时“重置”某些状态,可以考虑制作组件fully controlledfully uncontrolled with a key instead

P.S.注意到getDerivedStateFromProps的论点是propsstate而不是nextPropsprevProps

为了了解更多细节,

为了根据道具的变化进行更改,我们需要将prevPropsState存储在状态中,以检测更改。一个典型的实现看起来就像

代码语言:javascript
复制
static getDerivedStateFromProps(props, state) {
    // Note we need to store prevPropsState to detect changes.
    if (
      props.myPropsState !== state.prevPropsState
    ) {
      return {
        prevPropsState: state.myState,
        myState: props.myPropsState
      };
    }
    return null;
  }
票数 6
EN

Stack Overflow用户

发布于 2018-08-03 11:56:06

根据反应文档:

请注意,此方法在每个呈现上都会激发,而不管原因如何。这与UNSAFE_componentWillReceiveProps形成了对比,后者只在父程序导致重呈现时触发,而不是本地setState的结果。

每次调用setState()之后,您都会使用当前的道具有效地覆盖状态。因此,当您选中一个复选框时,将调用(e) => this.handleMethod(e, comp.myState),假设调用setState()来更新复选框的选中状态。但在此之后,将调用getDerivedStateFromProps() (在呈现之前的)来恢复该更改。这就是为什么从props无条件更新状态被认为是一种反模式。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51671593

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档