首页 > 解决方案 > 当我从 React 代码中的某个位置调用 setFormData() 时,为什么状态没有改变?

问题描述

我正在使用这样的 useState 钩子:

  const [formData, setFormData] = useState({
    company: "",
    title: "",
    location: "",
    from: "",
    to: "",
    current: false,
    description: "",
  });

我有两个看起来像这样的输入:

 <div className="form-group">
          <p>
            <input
              type="checkbox"
              name="current"
              checked={current}
              value={current}
              // use this to toggle the checkbox
              onChange={(e) => {
                if (!current) {
                  console.log("change");
                  setFormData({
                    ...formData,
                    to: null,
                    company: "test company",
                  });
                }
                setFormData({ ...formData, current: !current });
                toggleDisabled(!toDateDisabled);
                console.log({ formData });
              }}
            />{" "}
            Current Job
          </p>
        </div>

        <div className="form-group">
          <h4>To Date</h4>
          <input
            type="date"
            name="to"
            value={to}
            onChange={(e) => onChange(e)}
            disabled={current ? "disabled" : ""}
          />
        </div>

但是如果你看看我的第一个输入组,这部分代码根本没有做任何事情:

if (!current) {
                  console.log("change");
                  setFormData({
                    ...formData,
                    to: null,
                    company: "test company",
                  });
                }

所以,current正确地改变,当我点击复选框时,'current is toggling between true and false as it should. BUT, when it hits my if statement ofif(!current)` 的值和我调用 setFormData,绝对没有任何反应。但是,如果我将 'company: "test company" ' 添加到该函数正下方的 setFormData 函数中,则状态正在发生应有的变化。

那么这里到底发生了什么?我的 setFormData 函数如何仅在 if 语句之外工作?

标签: javascriptreactjs

解决方案


在复选框的 onChange 处理程序中,您应该检查复选框的新值而不是current状态中的属性。而且您实际上并不需要在复选框中定义一个值,因为您没有将它用于任何事情。在评论中您说“基本上我的最终目标是在选中复选框时将状态中的一个值更改为空”。当用户取消选中该复选框时,您似乎想将to属性更改为 null 并将公司更改为空白。

以下是您可以具体实现的方法。

<input
  type="checkbox"
  name="current"
  checked={current}
  onChange={(e) => {
    // If the checkbox is now checked, preserve formData.to and formData.company.
    // Otherwise, overwrite to with null and company with "test company".

    setFormData({
        ...formData,
        to: e.target.checked ? formData.to : null,
        company: e.target.checked ? formData.company : "test company",
        current: e.target.checked,
    });
  }}
/>

完整的测试组件

import React, { useState } from 'react';

const CheckboxTester = () => {
  const [formData, setFormData] = useState({
    to: "",
    company: "",
    current: false,
  });

  return (
    <>
      <input
        type="checkbox"
        name="current"
        checked={formData.current}
        onChange={(e) => {
          setFormData({
            ...formData,
            to: e.target.checked ? formData.to : null,
            company: e.target.checked ? formData.company : "test company",
            current: e.target.checked,
          });
        }}
      />
      <hr />
      <label>Current State</label>
      <br />
      <pre>
        {JSON.stringify(formData)}
      </pre>
    </>
  );
}

export default CheckboxTester;

推荐阅读