我对React钩子(useState)有一个奇怪的问题。
我有一个页面,该页面检查我的账单和我的银行帐户,并检查是否有薪水,然后将我的钱转移到不同的罐子中。该页面有2个按钮:检查前提条件(足够的薪水等),并运行脚本。
第一个(前提条件)按预期方式工作,输出(在下面的代码中为var currentstate)也按预期工作,当我更新状态(使用setPreconditions)时,什么都没有发生。
所以,我的想法是状态没有更新,直到我发现当我用状态(例如工资)更改其他字段时,页面会重新渲染并显示当前状态(状态前提条件)的正确数据。
为什么会这样?
const Bunq = ({auth}) => {
const [accounts, setAccounts] = useState([]);
const [preconditions, setPreconditions] = useState({run: false, succeeded: false, accountsExist: [], balanceSufficient: true, incomeSufficient: true, sparen: null, maandtotaal: 0, balance: null});
const [rekeningen, setRekeningen] = useState([]);
const [salaris, setSalaris] = useState(getLocalStorage('bunq_salaris') || '');
const [eigen_geld, setEigenGeld] = useState(getLocalStorage('bunq_eigen_geld') || '');
const [sparen, setSparen] = useState(0);
const [page_loaded, setPageLoaded] = useState(false);
const [script_running, setScriptRunning] = useState(false);
useEffect(() => {
setLocalStorage('bunq_salaris', salaris);
}, [salaris]);
useEffect(() => {
setLocalStorage('bunq_eigen_geld', eigen_geld);
}, [eigen_geld]);
.......................
const checkPreconditions = () => {
//check
//setScriptRunning(true);
const algemeen_account = getAccountByName("Algemeen");
let maandnummer = (new Date()).getMonth()+1;
let currentstate = preconditions;
currentstate.succeeded = true;
currentstate.maandtotaal = 0;
currentstate.incomeSufficient = true;
currentstate.balanceSufficient = true;
currentstate.balance = algemeen_account.balance.value;
rekeningen.map(rekening => {
currentstate.maandtotaal += rekening["totaal_" + maandnummer];
let foundaccount = getAccountByName(rekening.rekening);
if(foundaccount == null && rekening["totaal_" + maandnummer] > 0){
currentstate.succeeded = false;
currentstate.accountsExist.push(rekening.rekening)
console.log("Rekening bestaat niet: " + rekening.rekening);
}
});
if((parseFloat(algemeen_account.balance.value)) < salaris){
currentstate.balanceSufficient = false;
currentstate.succeeded = false;
}
if((currentstate.maandtotaal + eigen_geld) > salaris){
currentstate.incomeSufficient = false;
currentstate.sparen = 0;
currentstate.succeeded = false;
}else{
currentstate.sparen = (salaris - currentstate.maandtotaal - eigen_geld);
if(currentstate.balanceSufficient){
currentstate.sparen = (currentstate.sparen + (Math.round(algemeen_account.balance.value) - salaris));
}
//console.log(currentstate);
if(currentstate.sparen < 0){
currentstate.sparen = 0;
currentstate.incomeSufficient = false;
currentstate.succeeded = false;
}else{
currentstate.incomeSufficient = true;
}
}
setPreconditions(currentstate);
//setPreconditions('test');
console.log(currentstate, preconditions);
//setScriptRunning(false);
//this.setState({preconditions: currentstate});
}
.........................
return (<div><h1>Bunq</h1>
<DefaultTable data={rekeningen} columns={rekeningColumns} loading={rekeningen.length === 0} pageSize={15}/>
<Form>
<Row>
......................
<Button variant="primary" onClick={() => {checkPreconditions();console.log(preconditions);}} disabled={!page_loaded || script_running}>Controleer</Button>
</Row>
</Form>
<ListGroup>
{JSON.stringify(preconditions)}
{preconditions.balance !== null ?<ListGroup.Item variant="success">Huidig saldo Algemene rekening: {preconditions.balance}</ListGroup.Item> : ""}
{preconditions.accountsExist.map((rek, i) => {return <ListGroup.Item key={i} variant="danger">Rekening {rek} bestaat niet</ListGroup.Item>})}
{preconditions.balanceSufficient === false ? <ListGroup.Item variant="danger">Niet voldoende saldo. Salaris nog niet binnen?</ListGroup.Item> : ""}
{preconditions.incomeSufficient === false ? <ListGroup.Item variant="danger">Niet voldoende inkomen om alle rekeningen te betalen</ListGroup.Item> : ""}
{preconditions.sparen !== null ? <ListGroup.Item variant="success">Er wordt {preconditions.sparen} gespaard</ListGroup.Item> : ""}
</ListGroup>
</div>
);
}
答案 0 :(得分:2)
您正在改变状态,因此当您调用setPreconditions(currentstate)
时,您将使用完全相同的对象引用来更新状态,React会将其视为没有任何状态被更新。
您可以改为创建preconditions
对象的副本。
const checkPreconditions = () => {
const algemeen_account = getAccountByName("Algemeen");
let maandnummer = new Date().getMonth() + 1;
let currentstate = { ...preconditions };
// ...
}