Reputation: 440
I have a weird problem with React hooks (useState).
I have a page which checks my bills and my bank account and checks wether salary is in, and then moves my money to different jars. The page has 2 buttons: check preconditions (salary enough, etc), and run script.
The first one (preconditions) works as expected, also the output (in below code the var currentstate), when I update the state (with setPreconditions) nothing happens.
So, my thought was that state isnt updated, until I found out that when I changed some other field with state (for example salary) the page rerenders and the correct data for currentstate (state preconditions) is displayed.
Why is this happening?
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>
);
}
Upvotes: 1
Views: 318
Reputation: 112777
You are mutating your state, so when you call setPreconditions(currentstate)
you are updating the state with the exact same object reference, which React will treat as no state being updated.
You can create a copy of the preconditions
object instead.
const checkPreconditions = () => {
const algemeen_account = getAccountByName("Algemeen");
let maandnummer = new Date().getMonth() + 1;
let currentstate = { ...preconditions };
// ...
}
Upvotes: 2