Как обновить состояние React с помощью объекта данных с помощью хуков - PullRequest
0 голосов
/ 14 февраля 2020

У меня есть компонент со средством выбора даты, и я хотел бы изменить значение средства выбора даты в состоянии с помощью хуков, а также дату в самом средстве выбора даты, чтобы вы могли выбрать дату или нажмите кнопку, чтобы установить дату, например, 30 дней go.

. Это то, что я пробовал до сих пор:

const MyComp = () => {

  const [formData, setFormData] = useState({
    dateFrom: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
    dateTo: new Date()
  });

  const handleDateClick = interval => {
    setFormData({...formData, dateFrom: new Date(Date.now() - interval * 24 * 60 * 60 * 1000)});
    setFormData({...formData, dateTo: new Date()});
  };

  const handleOnChange = e => {
    setFormData({...formData, [e.target.name]: e.target.value});
  };

  return (
    <Button onClick={() => handleDateClick(30)} variant="secondary">30 days ago</Button>

    <DatePicker
      selected={formData.dateFrom}
      name="dateFrom"
      dateFormat="MMMM d, yyyy"
      onChange={value => handleOnChange({target: {name: "dateFrom", value}})}
    />
);

}

нажатие кнопки не имеет никакого эффекта, даже не отображая никаких ошибка, состояние не обновляется и значение в указателе даты не изменяется? Любая идея, пожалуйста?

1 Ответ

1 голос
/ 15 февраля 2020

Причина, по которой вы видите странное поведение, заключается в том, что ваш handleDateClick вызывает setFormData два раза подряд, что является проблемой, поскольку setFormData это асинхронно, то есть оно не будет немедленно отражать и обновлять ваше состояние.

См. этот вопрос SO для получения более подробной информации:

Итак, По сути, в конечном итоге вы обновляете dateFrom, а затем сразу после этого вызываете setFormData, и поскольку он использует старое состояние , вы никогда не увидите обновленное значение для dateFrom.

const handleDateClick = interval => {
  setFormData({ ...formData, dateFrom: ... })

  // uses the value of `dateFrom` from the "old state"
  // when you do `...formData`, then updates `dateTo`
  setFormData({ ...formData, dateTo: ... })
}

Я предлагаю вам объединить все ваши обновления внутри handleDateClick в один setFormData звонок. Судя по тому, как это выглядит, у вас нет причин делать два отдельных вызова.

Вот как вам следует подходить к этому:

function Button({ children, ...rest }) {
  return <button {...rest}>{children}</button>;
}

function MyComp() {
  const [formData, setFormData] = React.useState({
    dateFrom: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
    dateTo: new Date()
  });

  const handleDateClick = interval => {
    setFormData({
      dateTo: new Date(),
      dateFrom: new Date(Date.now() - interval * 24 * 60 * 60 * 1000)
    });
  };

  return (
    <>
      <Button onClick={() => handleDateClick(30)}>Click me!</Button>
      <p>
        <b>State:</b> {JSON.stringify(formData)}
      </p>
    </>
  );
}

Вот рабочий пример, если вы хотите см .:

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