You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中子组件状态变更后未更新数据的问题排查

问题:切换选中用户后表单数据不更新

我有一个用户列表,期望点击任意用户时,在页面右侧的表单组件中展示该用户的数据;未选中用户时,右侧只显示文本和「添加新用户」按钮,点击按钮后渲染空表单用于新增用户。但现在的问题是,第一次点击用户能正常显示数据,后续切换其他用户时,表单数据完全没变化。

主页面代码

const index = (props) => {
  const [selectedUser, setSelectedUser] = useState(null);
  const [state, setState] = useState("Index");

  const onChange = (item) => {
    setState("Edit");
    setSelectedUser(item);
  };

  const onClick = (e, item) => {
    if (e.type === "click" && e.clientX !== 0 && e.clientY !== 0) {
      onChange(item);
    } else {
      console.log('prevented "onClick" on keypress');
    }
  };

  const renderComponent = () => {
    switch (state) {
      case "Index":
        return (
          <>
            <div className="btn" onClick={(e) => setState("Edit")}>
              + New Staff
            </div>
            <img src="/storage/illustrations/collaboration.svg" />
          </>
        );
      case "Edit":
        return (
          <div>
            <StaffForm profile={selectedUser} />
          </div>
        );
    }
  };

  return (
    <>
      <div>
        <div>
          <h1>Staff</h1>
        </div>

        <div>
          <div>
            {profiles.map((item, index) => {
              return (
                <div key={index} onClick={(e) => onClick(e, item)}>
                  <input
                    type="radio"
                    name="staff"
                    checked={state === item}
                    onChange={(e) => onChange(item)}
                  />

                  <span>{item.user.name}</span>
                </div>
              );
            })}
          </div>
          <div>{renderComponent()}</div>
        </div>
      </div>
    </>
  );
};

StaffForm组件代码

const StaffForm = ({ profile }) => {
  const { data, setData, post, processing, errors, reset } = useForm({
    email: profile ? profile.user.email : "",
    name: profile ? profile.user.name : "",
    phone_number: profile ? profile.user.phone_number : "",
    avatar: profile ? profile.user.avatar : "",
  });
  const [file, setFile] = useState(data.avatar);
  const handleImageUpload = (e) => {
    setFile(URL.createObjectURL(e.target.files[0]));
    setData("avatar", e.target.files[0]);
  };
  const onHandleChange = (event) => {
    setData(
      event.target.name,
      event.target.type === "checkbox"
        ? event.target.checked
        : event.target.value
    );
  };

  return (
    <div>
      <ImageUpload
        name={data.name}
        file={file}
        handleImageUpload={handleImageUpload}
      />
      <TextInput
        type="text"
        name="name"
        value={data.name}
        autoComplete="name"
        isFocused={true}
        onChange={onHandleChange}
        placeholder={t("Name")}
        required
      />
      <TextInput
        type="text"
        name="phone_number"
        value={data.phone_number}
        autoComplete="phone_number"
        placeholder={t("Phone Number")}
        onChange={onHandleChange}
        required
      />
      <TextInput
        type="email"
        name="email"
        value={data.email}
        autoComplete="email"
        onChange={onHandleChange}
        placeholder={t("Email")}
        required
      />
    </div>
  );
};

解决方案

1. 修复表单数据不更新问题

useForm的初始值仅在组件首次挂载时设置,后续profile props变化不会自动更新表单。需要添加useEffect监听profile变化,手动重置表单数据:

const StaffForm = ({ profile }) => {
  const { data, setData, post, processing, errors, reset } = useForm({
    email: profile ? profile.user.email : "",
    name: profile ? profile.user.name : "",
    phone_number: profile ? profile.user.phone_number : "",
    avatar: profile ? profile.user.avatar : "",
  });
  const [file, setFile] = useState(data.avatar);

  // 监听profile变化,同步更新表单和头像文件
  useEffect(() => {
    if (profile) {
      const newData = {
        email: profile.user.email,
        name: profile.user.name,
        phone_number: profile.user.phone_number,
        avatar: profile.user.avatar,
      };
      reset(newData);
      setFile(newData.avatar);
    } else {
      reset({
        email: "",
        name: "",
        phone_number: "",
        avatar: "",
      });
      setFile("");
    }
  }, [profile, reset]);

  // 其余代码保持不变
};

2. 修复单选框选中状态错误

主页面中单选框的checked判断逻辑错误,state是字符串类型,不可能和用户对象item相等,应该用selectedUser来判断:

<input
  type="radio"
  name="staff"
  checked={selectedUser === item} // 修改此处
  onChange={(e) => onChange(item)}
/>

3. 简化冗余的点击事件判断

主页面中onClick函数里的clientX/clientY判断无意义,且可能导致正常点击失效,直接简化:

const onClick = (e, item) => {
  onChange(item);
};

甚至可以去掉外层div的onClick,仅保留单选框的onChange事件,更符合表单交互逻辑。

内容的提问来源于stack exchange,提问作者Abdelhk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 07:01:03