Реагирует на объект состояния обновления с использованием ловушек (useState), но без повторного отображения - PullRequest
1 голос
/ 16 апреля 2019

У меня странная проблема с перехватчиками React (useState).

У меня есть страница, которая проверяет мои счета и мой банковский счет и проверяет, находится ли зарплата, а затем переводит мои деньги в разные банки.На странице есть 2 кнопки: проверить предварительные условия (достаточно зарплаты и т. Д.) И запустить скрипт.

Первый (предварительные условия) работает должным образом, а также вывод (в приведенном ниже коде переменное текущее состояние), когда я обновляю состояние (с помощью 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 Ответ

2 голосов
/ 16 апреля 2019

Вы изменяете свое состояние, поэтому, когда вы вызываете setPreconditions(currentstate), вы обновляете состояние с точно такой же ссылкой на объект, который React будет рассматривать как состояние, которое не обновляется.

Вместо этого вы можете создать копию объекта preconditions.

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

  // ...
}
...