简体   繁体   中英

Why isn't my child component updating data when changing the state in React?

I have a list of users and I want to display in another component on the same page the user data in input fields for every user that I click on.

When no user is selected, I want the component to just render some text and a button to add a user. When the button is clicked the component renders the form with empty input fields so that we can add a new user.

I tried the following, but it's just showing the data for the first one I click on. It's not updating.

The main page:

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

The Staff Form Component:

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. First of all something you should avoid is the renderComponent() call.Check here the first mistake mentioned in this video . This will most likely fix your problem but even if it doesn't the video explains why it should not be used.
  2. Something else that caught my eye(possibly unrelated to your question but good to know) is the onChange function. When two pieces of state change together it is a potential source of problems, check out this article on when to use the useReducer hook .
  3. Also be careful with naming React Components, they need to be capital case, this question contains appropriate answers explaining it . (To only solve your problem stick to no.1 of this list, there are some improvements i'd do here overall for code quality and beauty, msg me for more details)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM