【问题标题】:I am unable to handle state correctly on Safari due to the useState hook由于 useState 挂钩,我无法在 Safari 上正确处理状态
【发布时间】:2020-07-13 17:34:18
【问题描述】:

更新组件状态时,我在 Safari 上遇到问题。我知道 Safari 的模式应该比 Chrome 更严格,但在这种情况下,我被困在了这个错误上。

我有这些输入:

问题是每次我选择下拉选项时,它都会删除其他输入的值。就像在本例中一样,我选择了 1 月,然后其他输入恢复为默认值 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;
  }
};

你能说出原因吗?

【问题讨论】:

    标签: javascript reactjs typescript ecmascript-6


    【解决方案1】:

    我看到handleBirthMonthChange 中有一个小错误。您正在调用 set state 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)
        }
      />
    );
    

    【讨论】:

    • 你能展示一些代码来更好地表达你的想法吗?
    猜你喜欢
    • 2022-01-26
    • 1970-01-01
    • 2020-01-17
    • 2021-04-10
    • 1970-01-01
    • 2020-02-22
    • 1970-01-01
    • 2021-06-16
    • 2020-05-31
    相关资源
    最近更新 更多