首页 > 解决方案 > 反应多个输入字段 onChange 不起作用

问题描述

如果用户单击添加输入按钮并将这些值存储为对象,我正在尝试添加一个额外的输入字段:

const {useState } = React;

const InviteUser = () => {
  const [userDetails, setUserDetails] = useState([
    {
      email: "",
      role: ""
    }
  ]);

  const handleCancel = () => {
    setUserDetails([
      {
        email: "",
        role: ""
      }
    ]);
  };

  const handleChange = (e, index) => {
    const { name, value } = e.target;

    let newUserDetails = [...userDetails];
    newUserDetails[index] = { ...userDetails[index], [name]: value };
    setUserDetails({ newUserDetails });
  };

  const addInput = () => {
    setUserDetails([...userDetails, { email: "", role: "" }]);
  };

  return (
    userDetails.length >= 0 && (
      <div>
        {[...userDetails].map((el, index) => (
          <form key={index + el} name={el}>
            <div>
              <input
                type="email"
                name="email"
                required
                onChange={(event) => handleChange(event, index)}
                value={el.email}
                style={{ marginTop: 17 }}
                placeholder="Enter Email Address"
              />
            </div>
            <div>
              <input
                type="text"
                name="roles"
                required
                value={el.role}
                style={{ marginTop: 17 }}
                placeholder="Role"
                onChange={(event) => handleChange(event, index)}
              />
            </div>
          </form>
        ))}
        <div>
          <button label="Invite Another?" onClick={addInput}>
            Add input
          </button>
        </div>
        <div>
          <button>Invite</button>
          <button onClick={() => handleCancel()}>Cancel</button>
        </div>
      </div>
    )
  );
};




 ReactDOM.render(
       <InviteUser/>,
       document.getElementById("react")
     );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>

状态是包含电子邮件和角色的对象数组:

const [userDetails, setUserDetails] = useState([
    {
      email: "",
      role: ""
    }
  ]);

handleChange 函数,它通过将一个对象(用户从每一行输入的值)推入一个数组来更新状态:

  const handleChange = (e, index) => {
    const { name, value } = e.target;

    let newUserDetails = [...userDetails];
    newUserDetails[index] = { ...userDetails[index], [name]: value };
    setUserDetails({ newUserDetails });
  };

和 addInput 函数添加新的输入字段行:

  const addInput = () => {
    setUserDetails([...userDetails, { email: "", role: "" }]);
  };

并返回 JSX:

return (
    userDetails.length >= 0 && (
      <InputsContainer>
        {[...userDetails].map((el, index) => (
          <form key={index + el} name={el} onSubmit={handleSubmit}>
            <EmailContainer>
              <input
                type="email"
                name="email"
                required
                onChange={(event) => handleChange(event, index)}
                value={el.email}
                style={{ marginTop: 17 }}
                placeholder="Enter Email Address"
              />
            </EmailContainer>
            <RolesContainer>
              <input
                type="text"
                name="roles"
                required
                value={el.role}
                style={{ marginTop: 17 }}
                placeholder="Role"
                onChange={(event) => handleChange(event, index)}
              />
            </RolesContainer>
          </form>
        ))}
        <InviteButtonContainer>
          <button label="Invite Another?" onClick={addInput}>
            Add input
          </button>
        </InviteButtonContainer>
        <SubmitButtonsContainer>
          <button onClick={(event) => handleSubmit(event)}>Invite</button>
          <button onClick={() => handleCancel()}>Cancel</button>
        </SubmitButtonsContainer>
      </InputsContainer>
    )
  );

我在这里做错了什么?

标签: javascripthtmlreactjsformsreact-hooks

解决方案


你有两个问题:

  1. setUserDetails您返回包装在对象中的数组时,而不是仅仅返回数组。
  2. 在角色字段中,您从el.roleinsted 中获取值el.roles

此外,由于您更新当前状态,基于之前的状态,最好使用功能更新

const {useState } = React;

const createNewEntry = () => ({ email: "", role: "" });

const InviteUser = () => {
  const [userDetails, setUserDetails] = useState(() => [createNewEntry()]);

  const handleCancel = () => {
    setUserDetails([createNewEntry()]);
  };

  const handleChange = (e, index) => {
    const { name, value } = e.target;

    setUserDetails(userDetails => {
      const newUserDetails = [...userDetails];
      newUserDetails[index] = { ...userDetails[index], [name]: value };
      return newUserDetails;
    });
  };

  const addInput = () => {
    setUserDetails([...userDetails, createNewEntry()]);
  };

  return (
    userDetails.length >= 0 && (
      <div>
        {[...userDetails].map((el, index) => (
          <form key={index + el} name={el}>
            <div>
              <input
                type="email"
                name="email"
                required
                onChange={(event) => handleChange(event, index)}
                value={el.email}
                style={{ marginTop: 17 }}
                placeholder="Enter Email Address"
              />
            </div>
            <div>
              <input
                type="text"
                name="roles"
                required
                value={el.roles}
                style={{ marginTop: 17 }}
                placeholder="Role"
                onChange={(event) => handleChange(event, index)}
              />
            </div>
          </form>
        ))}
        <div>
          <button label="Invite Another?" onClick={addInput}>
            Add input
          </button>
        </div>
        <div>
          <button>Invite</button>
          <button onClick={() => handleCancel()}>Cancel</button>
        </div>
      </div>
    )
  );
};

ReactDOM.render(
  <InviteUser/>,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>


推荐阅读