由于useState挂钩,我无法在Safari上正确处理状态

时间:2020-04-01 20:36:21

标签: javascript reactjs typescript ecmascript-6

更新组件状态时,我在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 :(得分:0)

我看到handleBirthMonthChange中存在小错误。您正在调用设置状态2次。通常,您不应一次更新2状态。由于setState是异步的。您可以合并状态并尝试。

这可能是不可预测行为的潜在问题。

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)
    }
  />
);