Phi*_*nin 4 javascript state reactjs
我有一个反应组件,它具有属性和状态。一些状态字段包含输入数据(从输入控件中提升),但状态中的某些字段也必须根据当前状态和属性进行计算:
问题:更新状态的计算字段的最佳方法是什么(基于状态和道具的其他字段)?
这样做的丑陋方式:
componentDidUpdate(){
this.setState({calculatedField:calculate(this.props,this.state)}))
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我将获得无限循环的更新,或者在最佳情况下(如果使用PureComponent,则是)双重渲染调用。
到目前为止,我发现的最佳解决方案(但仍然很丑):创建一个calculated处于状态的对象,该对象包含计算所得的字段并在componentWillUpdate中进行更新,避免使用setState:
componentWillUpdate(nextProps,nextState){
nextState.calculated.field1=f(nextProps,nextState)
}
Run Code Online (Sandbox Code Playgroud)
componentDidUpdate(){
this.setState({calculatedField:calculate(this.props,this.state)}))
}
Run Code Online (Sandbox Code Playgroud)
componentWillUpdate(nextProps,nextState){
nextState.calculated.field1=f(nextProps,nextState)
}
Run Code Online (Sandbox Code Playgroud)
这也是丑陋的解决方案,不建议React避免setState来改变状态。那么什么是正确的解决方案呢?
注意:
在我的真实应用程序中,由于渲染实际上是复杂的对象,因此无法在渲染过程中每次都重新计算f(a,b),因此我需要以某种方式对其进行缓存,并且最好的方式是处于状态。
如果您使用的是React 16.8.0及更高版本,则可以使用React hooks API。我认为这useMemo()可能是您需要的。例如:
import React, { useMemo } from 'react'
const MyComponent = ({ ...props }) => {
const calculatedValue = useMemo(
() => {
// Do expensive calculation and return.
},
[a, b]
)
return (
<div>
{ calculatedValue }
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
有关更多详细信息,请参阅React文档。
您的第一次尝试是解决此问题的正确方法。但是,您需要添加检查以查看状态是否确实发生了变化:
componentDidUpdate(prevProps, prevState){
if(prevState.field !== this.state.field){
this.setState({calculatedField:calculate(this.props,this.state)}))
}
}
shouldComponentUpdate(nextProps, nextState) {
return this.state.calculatedField !== nextState.calculatedField
}
Run Code Online (Sandbox Code Playgroud)
您需要检查在计算方法中使用的状态和道具,并确保它们在再次更新状态之前已更改。这将防止无限循环。
| 归档时间: |
|
| 查看次数: |
5495 次 |
| 最近记录: |