繁体   English   中英

为什么 React state 第二次调用时没有变化?

[英]Why does React state not change when called a second time?

我目前正在构建一个利息计算器。 calcInfo的属性值可以使用滑块完美更改,但只要我添加calculateResult() ,就不会再更改任何值,而是使用默认值。

为什么会发生这种情况,我该如何解决?

const CalculatorContext = React.createContext();
const CalculatorProvider = (props) => {

  const calculatorInformation = {
    initial_investment: 10000,
    monthly_contribution: 1000,
    length_of_time_years: 40,
    interest_rate_per_year: 7,
    financial_data: [],
    result: 2713059,
  }
  const [calcInfo, setCalcInfo] = useState(calculatorInformation);
  
  const changeCalculation = (value, property) => {
      console.log("-- hallo")
      setCalcInfo({...calcInfo, [property]: value})
      setCalcInfo({...calcInfo, financial_data: calculateResult()})
  }

  const calculateResult = () => {
    const initial_investment = calcInfo.initial_investment
    const contribution_per_month = calcInfo.monthly_contribution
    const contribution_per_year = contribution_per_month * 12
    const years = calcInfo.length_of_time_years
    const interest_rate = parseFloat(calcInfo.interest_rate_per_year)
    let result = initial_investment
  
    const years_interests = []
    const years_results = []

    for (let year = 0; year < years; year++) {
      result += contribution_per_year
      result = result / 100 * (100 + interest_rate)
  
      years_interests.push(year)
      years_results.push(result)
    }

    const financial_data = {
      labels: years_interests,
      datasets: [{
          label: 'Vermögensentwicklung über gewählten Zeitraum',
          data: years_results,
      }]
    }

    return financial_data
  }
    
  return (
    <CalculatorContext.Provider value={{calcInfo, changeCalculation}}>
      {props.children}
    </CalculatorContext.Provider>
  )
}
<input className="calculator-slider" type="range" min="1" max="100" step="1" value={length_of_time_years}
        onChange={(e) => context.changeCalculation(parseInt(e.target.value), "length_of_time_years")}></input>

按原样,您的状态设置 function 已关闭当前版本的 state(截至该渲染)。 确保始终使用最新版本 state 的一种方法是使用回调 function:

const changeCalculation = (value, property) => {
  setCalcInfo(c => ({...c, [property]: value}))
  setCalcInfo(c => ({...c, financial_data: calculateResult()}))
}

编辑:顺便说一句,如果您需要计算结果中更新版本的calcInfo ,我建议将calcInfo直接传递给calcuateResult ,或者我想将其作为效果运行。

当然,最好的解决方案可能是根本不financial_data存储在 state 中,因为它是纯粹派生的 state,因此对于 state 的 rest 是多余的。

派生 State

编辑 2:只是通过不存储financial_data来扩展我的意思。 由于它是纯派生 state,因此您可以随时从 function 中获取此信息,而不是将其冗余存储。

因此,您可以使这个 function 独立于某处:

const getFinancialData = (calcInfo) => {
  const initial_investment = calcInfo.initial_investment
  const contribution_per_month = calcInfo.monthly_contribution
  const contribution_per_year = contribution_per_month * 12
  const years = calcInfo.length_of_time_years
  const interest_rate = parseFloat(calcInfo.interest_rate_per_year)
  let result = initial_investment
  
  const years_interests = []
  const years_results = []

  for (let year = 0; year < years; year++) {
    result += contribution_per_year
    result = result / 100 * (100 + interest_rate)

    years_interests.push(year)
    years_results.push(result)
  }

  const financial_data = {
    labels: years_interests,
    datasets: [{
        label: 'Vermögensentwicklung über gewählten Zeitraum',
        data: years_results,
    }]
  }

  return financial_data
}

然后,在您需要此信息的任何组件中,只需调用 function。此时您将始终拥有最新信息,而不必担心数据不同步:

const SomeComponent = () => {
  const {calcInfo} = useContect(CalculatorContext);

  // Purely derived state
  const financialData = getFinancialData(calcInfo)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM