使用钩子(useState)反应更新状态对象有效,但没有重新渲染

时间:2019-04-16 08:35:21

标签: reactjs react-hooks

我对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>
);

}

1 个答案:

答案 0 :(得分:2)

您正在改变状态,因此当您调用setPreconditions(currentstate)时,您将使用完全相同的对象引用来更新状态,React会将其视为没有任何状态被更新。

您可以改为创建preconditions对象的副本。

const checkPreconditions = () => {
  const algemeen_account = getAccountByName("Algemeen");
  let maandnummer = new Date().getMonth() + 1;
  let currentstate = { ...preconditions };

  // ...
}