Я не могу правильно обработать состояние в Safari из-за ловушки useState - PullRequest
0 голосов
/ 01 апреля 2020

У меня проблемы с Safari при обновлении состояния компонента. Я понимаю, что в Safari предполагается более строгий режим, чем Chrome, но в этом случае я застрял на этой ошибке.

У меня есть следующие входные данные:

enter image description here

Проблема в том, что каждый раз, когда я выбираю опцию из выпадающего списка, он удаляет значение другого входа. Как и в этом случае, я выбрал январь, а затем для другого входа вернулось значение по умолчанию N/A.

Вкл. Chrome и Firefox, это работает правильно. Проблема только в Safari.

См. Некоторый код:

let birthDays: number[] = [0];
const [birthDayState, setBirthDays] = useState(birthDays);
// userDetails is an object/prop which holds all of the information of a user
const [userInput, setUserInput] = useState({} as typeof userDetails);

const handleBirthMonthChange = (event: React.SyntheticEvent): void => {
    const { value, name } = event.target as HTMLSelectElement;
    setUserInput({ ...userInput, [name]: value });
    setBirthDays(loadDays(year, value));
};

const handleDayChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
    const field = event.target.name;
    console.log({ field });
    setUserInput({ ...userInput, [field]: event.target.value });
};

return (
  <GetToKnowMeForm              
    birthDates={birthDayState}
    birthDay={userInput?.birthday}
    birthMonth={userInput?.birthMonth}
    handleBirthMonthChange={handleBirthMonthChange}              
    handleChange={(e: React.ChangeEvent<HTMLInputElement>) => handleDayChange(e)}
  />
)

Так что мне интересно, где я терплю неудачу. Есть идеи по этому поводу? Я понял, что на этой функции метод loadDays:

const handleBirthMonthChange = (event: React.SyntheticEvent): void => {
    const { value, name } = event.target as HTMLSelectElement;
    setUserInput({ ...userInput, [name]: value });
    setBirthDays(loadDays(year, value));
};

Не работает ли один, вот как это выглядит:

export const fullDays = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31];

export const loadDays = (year: number, month?: string): number[] => {
  if (month) {
    if (year === undefined || year === null) { year = new Date().getFullYear(); }

    const currentMonth = monthByDate(new Date(`${month}/${year}`));
    const date = new Date(year, currentMonth, 1);
    const days = [];
    while (date.getMonth() === currentMonth) {
      days.push(new Date(date).getDate());
      date.setDate(date.getDate() + 1);
    }
    return days;
  } else {
    return fullDays;
  }
};

Можете ли вы сказать, почему?

1 Ответ

0 голосов
/ 01 апреля 2020

Я вижу, есть небольшая ошибка в handleBirthMonthChange. Вы звоните установить состояние 2 раза. Как правило, вы не должны обновлять 2 состояния один раз. Поскольку setState является асин c. Вы можете объединить состояние и попробовать.

Это может быть потенциальной проблемой непредсказуемого поведения.

const [userDetail, setUserDetail] = useState({
  birthDays: [0],
  userInput: {}
});
const { birthDays, userInput } = userDetail;
const handleBirthMonthChange = (event: React.SyntheticEvent): void => {
  const { value, name } = event.target as HTMLSelectElement;
  setUserDetail({
    birthDays: loadDays(year, value),
    userInput: { ...userInput, [name]: value }
  });
};

const handleDayChange = (
  event: React.ChangeEvent<HTMLInputElement>
): void => {
  const field = event.target.name;
  setUserDetail({
    birthDays,
    userInput: { ...userInput, [field]: event.target.value }
  });
};

return (
  <GetToKnowMeForm
    birthDates={birthDayState}
    birthDay={userInput?.birthday}
    birthMonth={userInput?.birthMonth}
    handleBirthMonthChange={handleBirthMonthChange}
    handleChange={(e: React.ChangeEvent<HTMLInputElement>) =>
      handleDayChange(e)
    }
  />
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...