setState не обновляет значения массива - PullRequest
0 голосов
/ 07 мая 2020

Здесь массив (Boolean):

  const [state, setState] = React.useState({
    [`${"checkedA"+index}`]: false, //checkedA0
    [`${"checkedB"+index}`]: false, //checkedB0
    [`${"checkedC"+index}`]: false, //checkedC0
    [`${"checkedD"+index}`]: false, //checkeD0

  });

И код проблемы:

    const [countChecked, setCountChecked] = React.useState(0);
    const [previous, setPrevious] = React.useState(0);

    const handleChange = (event) => {


    if(countChecked<1){

      setState({ ...state, [event.target.name]: event.target.checked }); //WORK
      setCountChecked(countChecked+1); //WORK
      setPrevious(event.target.name); //WORK

    }else{

      setState({ ...state, [previous]: false }); //WORKS 
      //setState({ ...state, [event.target.name]: event.target.checked }); //NO WORKS

    }

  };

Я не понимаю, почему, если я использую несколько раз setState равно не работает работает только один раз (строка) внутри оператора else. Спасибо!

Ответы [ 3 ]

2 голосов
/ 07 мая 2020

setState вызывает метод рендеринга, и управление не возвращается в блок else после первого вызова метода setState. Просто используйте один метод setState для обоих изменений, например:

setState({ ...state, [previous]: false, [event.target.name]: event.target.checked });
1 голос
/ 07 мая 2020

Проблема проста.

В операторе else в обоих обновлениях состояния вы распространяете предыдущее состояние и передаете новое обновленное значение. Однако вы должны знать, какие обновления состояния в обработчиках являются пакетными, т.е. если вы вызываете setState несколько раз, результат всех обновлений состояния объединяется в один и обновляется

При пакетировании изменения, которое вы внесли в [previous] состояние потеряно, потому что следующий вызов обновления состояния также распространяет состояние, и поскольку обновления состояния асинхронны, c state в

 setState({ ...state, [event.target.name]: event.target.checked }); 

также будет ссылаться на исходное состояние до того, как был вызван какой-либо setState

Решение здесь для выполнения всех обновлений в одном вызове setState, например

  setState({ 
    ...state, 
   [previous]: false,
   [event.target.name]: event.target.checked 
  }); 

Однако вы должны отметить, что всякий раз, когда вы используете предыдущее состояние, как и выше, лучше использовать функциональный setState, а также сохраните значения событий перед их использованием, так как события Syntheti c повторно используются и обнуляются React

const { name, checked } = e.target;
setState(prevState => ({ 
    ...prevState, 
   [previous]: false,
   [name]: checked 
  }));

В вашем блоке if все три обновления состояния работают, потому что когда они группируются, они ссылаются на разные средства обновления состояния

0 голосов
/ 07 мая 2020

Вот рабочий код вашего logi c:

  const index = 0;
  const [state, setState] = React.useState({
    [`${"checkedA"+index}`]: false,
    [`${"checkedB"+index}`]: false,
    [`${"checkedC"+index}`]: false,
    [`${"checkedD"+index}`]: false,
  });

  const [countChecked, setCountChecked] = React.useState(0);
  const [previous, setPrevious] = React.useState('');

  const handleChange = (event) => {
    if(countChecked < 1) {
      setState({ ...state, [event.target.name]: event.target.checked });
      setCountChecked(count => count + 1);
      setPrevious(event.target.name);
    } else {
      setState({ ...state, [event.target.name]: event.target.checked });
      setPrevious(false);
    }
  }

  return (
    <div className="membership-all-steps">
      <Checkbox
        name={`${"checkedA"+index}`}
        label="checkedA0"
        onChange={handleChange}
      />
      <Checkbox
        name={`${"checkedB"+index}`}
        label="checkedB0"
        onChange={handleChange}
      />
      <Checkbox
        name={`${"checkedC"+index}`}
        label="checkedC0"
        onChange={handleChange}
      />
      <Checkbox
        name={`${"checkedD"+index}`}
        label="checkedD0"
        onChange={handleChange}
      />
    </div>
  );
}

Но все же я не уверен, чего вы хотите достичь с помощью состояния countChecked & previous. Если вы объясните, для каких целей вы используете это состояние, возможно, я помогу вам и с вашим logi c. Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...