用计算字段反应状态 [英] React state with calculated fields

查看:87
本文介绍了用计算字段反应状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个反应成分,它具有属性和状态.一些状态字段包含输入数据(从输入控件中提升),但状态中的某些字段也必须根据当前状态和属性进行计算:

I have a react component, which has properties and state. Some fields of state contain input data (uplifted from input control), but there is also fields in the state that must be Calculated based on current State and Props:

问题:更新状态计算字段(基于状态字段和道具的其他字段)的最佳方法是什么?

The question: what is the best way to update calculated fields of the state (based on other fields of state and props)?

这样做的丑陋方式:

componentDidUpdate(){
    this.setState({calculatedField:calculate(this.props,this.state)})) 
}

在这种情况下,我会得到无限的更新循环,或者在最佳情况下(如果使用PureComponent的话)会出现双重渲染调用.

In this case I get infinite loop of updates or in the best case (if I use PureComponent) double rendering invocation.

我到目前为止发现的最佳解决方案(但仍然很丑): 将创建一个状态为calculated的对象,该对象包含计算所得的字段并在componentWillUpdate中进行更新,从而避免setState:

The best solution I found so far (but still ugly): Is to create a calculated object in state, which contains calculated fields and updated in componentWillUpdate avoiding setState:

componentWillUpdate(nextProps,nextState){
   nextState.calculated.field1=f(nextProps,nextState)
}

class ParentComponent extends React.Component {
  constructor(props, ctx) {
    super(props,ctx)
    this.state={A:"2"}
  }

  render() {
    console.log("rendering ParentComponent")
    return <div>
      <label>A=<input value={this.state.A} onChange={e=>{this.setState({A:e.target.value})}} /></label> (stored in state of Parent component)
      <ChildComponent A={this.state.A} />
    </div>
  }
}

class ChildComponent extends React.PureComponent {
  constructor(props,ctx) {
    super(props,ctx);
    this.state={
      B:"3",
      Calculated:{}
    }
  }

  render() {
    console.log("rendering ChildComponent")
    return <div>
      <label>B=<input value={this.state.B} onChange={e=>{this.setState({B:e.target.value})}} /></label> (stored in state of Child component state)
      <div>
        f(A,B)=<b>{this.state.Calculated.result||""}</b>(stored in state of Child component)
        <button onClick={e=>{ this.setState({Calculated:{result:new Date().toTimeString()}}) }}>Set manual value</button>
      </div>
    </div>
  }

  componentWillUpdate(nextProps, nextState) {
    this.state.Calculated.result = getCalculatedResult(nextProps.A, nextState.B)
  }

  componentWillReceiveProps(nextProps) {
    this.state.Calculated.result = getCalculatedResult(nextProps.A, this.state.B)
  }

  componentWillMount() {
    this.state.Calculated.result = getCalculatedResult(this.props.A, this.state.B)
  }
}

function getCalculatedResult(a,b) {
  const aNum = Number(a)||0
  const bNum = Number(b)||0;
  const result = (aNum*bNum).toString();
  return result;
}

ReactDOM.render(<ParentComponent/>, document.getElementById('root'));

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.development.js"></script>
<div id="root"></div>

这也是丑陋的解决方案,不建议React避免setState来改变状态.那么什么是正确的解决方案?

This is also ugly solution and React does not recommended to mutate state avoiding setState. So what is right solution for that?

注意:

在我的真实应用程序中,由于渲染实际上是复杂的对象,因此无法在渲染过程中每次都重新计算f(a,b),因此我需要以某种方式对其进行缓存,并且最好的方式是处于状态.

In my real application I cannot recalculate f(a,b) every single time during rendering, because it's actually complex object, so I need to cache it somehow and the best way is in the state.

推荐答案

如果您使用的是React 16.8.0及更高版本,则可以使用React hooks API.我认为这可能是您可能需要的useMemo()钩子.例如:

If you are using React 16.8.0 and above, you can use React hooks API. I think it's useMemo() hook you might need. For example:

import React, { useMemo } from 'react'

const MyComponent = ({ ...props }) => {
  const calculatedValue = useMemo(
    () => {
      // Do expensive calculation and return.
    },
    [a, b]
  )

  return (
    <div>
      { calculatedValue }
    </div>
  )
}

有关更多详细信息,请参见反应文档

For more details, refer to the React documentation

这篇关于用计算字段反应状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆