我觉得我正在以适当的方式致电setState,但想确保我没有在错误的地方打电话。查看是否有人可以发现错误。在控制台日志中,状态保存的是先前的值,而不是新清除的值。这是我的代码:
componentWillReceiveProps(nextProps) {
if (nextProps.value !== this.state.value && typeof nextProps.value !== 'undefined'){
let changeVal = nextProps.value;
let changeDisplay = nextProps.value;
if(this.props.entryType === 'date') changeVal = Moment(nextProps.displayValue).format(this.props.format).toString();
if(this.props.entryType === 'currency'||this.props.entryType === 'number'){
if(isNaN(parseFloat(changeVal))){
changeVal = 0;
changeDisplay = 0;
}
}
if(this.props.entryType === 'drop' || this.props.entryType === 'boolean'){
if(this.props.options) {
this.props.options.map(x => {
if (x.value == changeVal || x.sortOrder == changeVal){
changeDisplay = x.label;
changeVal = x.value;
}
})
}
}
this.setState({value: changeVal, displayValue: changeDisplay, selectValue:{value:changeVal, label:changeDisplay}}, ()=>{
console.log("current displayValue",this.state, nextProps, this.props)
});
}
}
很明显,我在setState之后调用控制台,但是该值不会更新。
编辑:感谢您的答复。我将尝试撕裂道具更新状态方法。我创建了一个拖放系统,可以在其中拖放项目。效果很好,但是在该层次结构中具有“容器”>“树”>“项目”>“ QueryValue”组件。这里的问题在于,容器需要了解整个树,才能将其构建出来,但是对内容的编辑在QueryValue中进行。因此,我有一种方法可以遍历整个链,该方法可以让我将任何更改通知Container。但是我可能需要将Container数据与QueryValue数据分离。
答案 0 :(得分:3)
您的代码非常复杂,因此我建议尝试对其进行重构。
但是无论如何,我建议使用“ componentDidUpdate”
反应文档(针对“ componentDidUpdate”):
https://reactjs.org/docs/react-component.html#componentdidupdate
反应文档(用于“ UNSAFE_componentWillReceiveProps”):
https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops
Note:
Using this lifecycle method often leads to bugs and inconsistencies, and for that reason it is going to be deprecated in the future.
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.
For other use cases, follow the recommendations in this blog post about derived state.
If you used componentWillReceiveProps for re-computing some data only when a prop changes, use a memoization helper instead.
If you used componentWillReceiveProps to “reset” some state when a prop changes, consider either making a component fully controlled or fully uncontrolled with a key instead.
In very rare cases, you might want to use the getDerivedStateFromProps lifecycle as a last resort.
答案 1 :(得分:1)
正如@Tzook Bar Noy所解释的,React团队强烈建议不要使用componentWillReceiveProps
生命周期方法。您可以使用componentDidUpdate
,但在该函数中使用setState
也被认为是不好的做法:如果您无法正确管理边界,则可能导致无限循环componentWillUpdate -> setState -> componentWillUpdate -> setState -> etc
。>
由于您在代码中未使用实例方法,因此我建议您使用新的getDerivedStateFromProps
静态方法。当组件安装和组件更新时,将使用当前的props和state调用此方法。它使用返回的对象来有选择地更新组件状态。
检入react docs是否适用于您的用例。有趣的文章:https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html
您的代码可能如下所示:
getDerivedStateFromProps(props, state) {
if (props.value !== state.value && typeof props.value !== 'undefined') {
let changeVal = props.value
let changeDisplay = props.value
if (entryType === 'date')
changeVal = Moment(props.displayValue)
.format(format)
.toString()
if (
entryType === 'currency' ||
entryType === 'number'
) {
if (isNaN(parseFloat(changeVal))) {
changeVal = 0
changeDisplay = 0
}
}
if (
entryType === 'drop' ||
entryType === 'boolean'
) {
if (options) {
options.map(x => {
if (x.value == changeVal || x.sortOrder == changeVal) {
changeDisplay = x.label
changeVal = x.value
}
})
}
}
return {
value: changeVal,
displayValue: changeDisplay,
selectValue: { value: changeVal, label: changeDisplay }
}
}
return null
}