对我来说,componentWillReceiveProps和getDerivedStateFromProps到底是个微妙的问题。因为,我在使用getDerivedStateFromProps时遇到了一个问题:
// 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
发布于 2018-08-04 14:09:54
最后,我解决了我的问题。这是一次痛苦的调试:
// 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之间的差异。
// 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 ),但是由于某些原因,我不得不修改这种技术。
我的措辞可能有些混乱,但我希望你能明白。
发布于 2018-08-03 11:35:02
getDerivedStateFromProps并不是componentWillReceiveProps的直接替代品,这完全是因为在每次更新之后调用它,无论是状态的更改、道具的更改还是父级的重新呈现。
无论如何,简单地从getDerivedStateFromProps 返回状态并不是正确的方法,您需要在返回值之前对状态和道具进行比较。否则,每更新一次,状态就会被重置为支持,并且循环将继续。
根据文档
在调用render方法之前,在初始挂载和后续更新中都会调用
getDerivedStateFromProps。它应该返回一个对象来更新状态,或者null返回什么都不更新。 此方法存在于一些罕见的用例中,在这种情况下,状态依赖于随时间而变化的道具。例如,可以方便地实现一个<Transition>组件,该组件比较它以前的子组件和下一个子组件,以决定它们中的哪一个要进入和输出。 派生状态会导致冗长的代码,使您的组件难以考虑。确保您熟悉更简单的替代方案: 如果您需要执行副作用(例如,数据获取或动画)以响应道具的更改,则使用componentDidUpdate生命周期。 如果您只想在道具更改时才重新计算某些数据,请使用memoization助手。 如果您想在道具更改时“重置”某些状态,可以考虑制作组件fully controlled或fully uncontrolled with a key instead。
P.S.注意到getDerivedStateFromProps的论点是props和state而不是nextProps和prevProps
为了了解更多细节,
为了根据道具的变化进行更改,我们需要将prevPropsState存储在状态中,以检测更改。一个典型的实现看起来就像
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;
}发布于 2018-08-03 11:56:06
根据反应文档:
请注意,此方法在每个呈现上都会激发,而不管原因如何。这与
UNSAFE_componentWillReceiveProps形成了对比,后者只在父程序导致重呈现时触发,而不是本地setState的结果。
每次调用setState()之后,您都会使用当前的道具有效地覆盖状态。因此,当您选中一个复选框时,将调用(e) => this.handleMethod(e, comp.myState),假设调用setState()来更新复选框的选中状态。但在此之后,将调用getDerivedStateFromProps() (在呈现之前的)来恢复该更改。这就是为什么从props无条件更新状态被认为是一种反模式。。
https://stackoverflow.com/questions/51671593
复制相似问题