![](/img/trans.png)
[英]How to change one of the state object value correctly with useState React
[英]How to change state of object correctly?
我有一个 object,我想在单击按钮时更改值。 无论我做什么,我只能在第二次点击时更改 state。 第一次点击总是为我返回初始值。 有人可以指导我这里有什么问题吗?
初始 state:
const [currencyResult, setCurrencyResult] = useState({
amount: "1",
currencyFrom: "EUR",
currencyTo: "USD",
multipliedAmount: "",
date: ""
});
onclick:
setCurrencyResult({
amount: currencyResult.amount,
currencyFrom: currencyResult.currencyFrom,
currencyTo: currencyResult.currencyTo,
multipliedAmount: currencyRate * currencyResult.amount,
date: Date.now()
})
整个代码是:
import React, { useState, useEffect } from 'react';
import { Form, Icon } from 'semantic-ui-react';
import { Link } from 'react-router-dom';
import ShowResult from './ShowResult';
import "../styles/HomePage.css"
const HomePage = (props) => {
const options = [
{ key: 'EUR', value: 'EUR', text: 'EUR' },
{ key: 'USD', value: 'USD', text: 'USD' },
{ key: 'CHF', value: 'CHF', text: 'CHF' },
];
const baseUrl = `https://api.exchangeratesapi.io/latest?base=`
const [currencyResult, setCurrencyResult] = useState({
amount: "1",
currencyFrom: "EUR",
currencyTo: "USD",
multipliedAmount: "",
date: ""
});
const [currencyDatabase, setCurrencyDatabase] = useState([]);
const [hasError, setHasError] = useState(false);
const [errorMessage, setErrorMessage] = useState("");
const { amount, currencyFrom, currencyTo, multipliedAmount, date } = currencyResult;
const [currencyRate, setCurrencyRate] = useState("");
const [clicked, setClicked] = useState(false);
const formValidation = () => {
if (currencyResult.currencyFrom === currencyResult.currencyTo) setErrorMessage("Equal currencies")
if (!currencyResult.amount) setErrorMessage("no number given")
if (currencyResult.amount.charAt[0] === "-") setErrorMessage("no minus numbers")
if (currencyResult.amount === "0") setErrorMessage("can't convert 0")
if (errorMessage) setHasError(true)
}
const calculationHandler = async () => {
formValidation()
if (hasError) {
return
} else {
setClicked(!false)
const fetchData = await fetch(`${baseUrl}${currencyResult.currencyFrom}&symbols=${currencyResult.currencyTo}`);
const response = await fetchData.json();
setCurrencyRate(await Object.values(response.rates)[0])
setCurrencyDatabase([...currencyDatabase, currencyResult])
setCurrencyResult({
amount: currencyResult.amount,
currencyFrom: currencyResult.currencyFrom,
currencyTo: currencyResult.currencyTo,
multipliedAmount: currencyRate * currencyResult.amount,
date: Date.now()
})
}
}
if (currencyDatabase) props.getCalculations(currencyDatabase);
const changeCurrency = () => {
setCurrencyResult({
...currencyResult,
currencyTo: currencyResult.currencyTo
})
setCurrencyResult({
...currencyResult,
currencyFrom: currencyResult.currencyFrom
})
}
return (
<div className="app">
<div className="header">
<h1 className="headline">Convert currencies in real-time.</h1>
</div>
<div className="form-content">
<Form className="box-background">
<Form.Group style={{ margin: "auto" }} >
<Form.Input
required
label='Amount'
placeholder='Amount'
value={currencyResult.amount}
onChange={(e, { value }) => setCurrencyResult({
...currencyResult,
amount: value
})}
type="number"
/>
<Form.Select
required
placeholder="From"
label="From"
value={currencyResult.currencyFrom}
onChange={(e, { value }) => setCurrencyResult({
...currencyResult,
currencyFrom: value
})}
options={options}
/>
<Icon name="exchange" onClick={changeCurrency} size="large" />
<Form.Select
required
placeholder="To"
label="To"
value={currencyResult.currencyTo}
onChange={(e, { value }) => setCurrencyResult({
...currencyResult,
currencyTo: value
})}
options={options}
/>
<Form.Button
className="btn-div"
onClick={calculationHandler}>
Convert
</Form.Button>
</Form.Group>
<Form.Field className="error-msg">
{hasError ? <p>{errorMessage}</p> : null}
</Form.Field>
</Form>
<Link to="/result" className="conversion-history">
<span>View conversion history {">"}</span>
</Link>
</div>
{currencyResult && <ShowResult currencyResult={currencyResult} />}
</div>
);
}
export default HomePage;
使用功能更新。
如果使用以前的 state 计算新的 state,则您可以 [并且应该] 将 function 传递给 setState。 function 将接收先前的值,并返回更新的值。
https://reactjs.org/docs/hooks-reference.html#usestate
const calculationHandler = async () => {
// async stuff
setCurrencyResult(previous => {
return {
amount: previous.amount,
currencyFrom: previous.currencyFrom,
currencyTo: previous.currencyTo,
multipliedAmount: currencyRate * previous.amount,
date: Date.now()
}
})
}
}
与 class 组件中的 setState 方法不同,useState 不会自动合并更新对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.