[英]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 是多余的。
编辑 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.