究竟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
Box" id={`someid`}
onChange={(e) => this.handleMethod(e,comp.myState)}
checked={myState.indexOf(comp.myState) > -1} />
反应版本:16.4.1
无论如何,只需从getDerivedStateFromProps返回状态不正确,您需要在返回值之前比较状态和props.此外,每次更新状态都会重置为道具并且循环继续
按照docs
getDerivedStateFromProps
is invoked right before calling the render
method,both on the initial mount and on subsequent updates. It should
return an object to update the state,ornull
to update nothing.This method exists for rare use cases where the state depends on
changes in props over time. For example,it might be handy for
implementing a
component that compares its prevIoUs and
next children to decide which of them to animate in and out.Deriving state leads to verbose code and makes your components
difficult to think about. Make sure you’re familiar with simpler
alternatives:If you need to perform a side effect (for example,data fetching
or an animation) in response to a change in props,use
componentDidUpdate
lifecycle instead.If you want to re-compute some data only when a prop changes,use
amemoization
helper instead.If you want to “reset” some state when a prop changes,consider
either making a componentfully controlled
orfully uncontrolled
.
with a key instead
附:请注意,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;
}