【问题标题】:Display multiple dynamic input fields in react, based on a changing state variable?根据不断变化的状态变量在反应中显示多个动态输入字段?
【发布时间】:2020-07-19 04:33:34
【问题描述】:

所以,我正在构建我的第一个 React 应用程序,它连接到 Flask 后端。我有一个从 Python 程序中获取字典的特定功能组件,并且我已将其保存在状态变量中(使用 useState、setVariables 完成)。 对象的类型

{'A':'x', 'B':'y', 'C':2},

这些都是变量,每次渲染都需要是动态的,只基于这个对象。 根据这个对象的当前状态,我想在

中显示这个对象的键值对
<label>insertkey</label>
<input type="text" name = "insertkey" value=insertvalue/>

此外,我希望能够保存对这些值所做的任何更改,并将其写入状态变量,以便我可以将它们发送回我的 Flask 后端。

我尝试遍历每个,并插入如下:

const [fields, setFields] = useState({});
//intermediate code for fetching and setting the state 

useEffect(() => {
  for (const [key, value] of Object.entries(fields)) {
    console.log(`${key}:${value}`);
    insert = insert + `<label> ${key} </label> <input type = 'text' value = ${value} name = ${key} onChange=${changedData()}></input><br/>`
  }

  document.getElementById('fields_form').innerHTML = insert;
});
const changedData = (evt) => {
  setFields({ [evt.target.name]: evt.target.value });
  console.log(evt.target.value);
}

//some intermediate code

return (
  <div>
    <form onSubmit={submitFunction}>
      <p id='fields_form'>

      </p>
      <input type="submit" value="Submit"></input>
    </form>
  </div>
);

但是当我这样做时,状态被设置为“未定义”。

我很想听听一些实现这一点的方法。也许这是一个非常小的修复,我错过了它,或者也许有一种不同的方法可能更合适。

【问题讨论】:

    标签: html reactjs dom


    【解决方案1】:

    简单:

    const Form = () => {
      const [values, setValues] = useState({});
      const onChange = (e) => {
        const name = e.target.name;
        let value = e.target.value;
        setValues({ ...values, [name]: value });
      };
      const onSubmit = (e) => {
        // send data or save it to local store
        api.send(values)
      };
      return (
        <form encType="multipart/form-data">
          <input
            type="text"
            name="email"
            value={value["email"]}
            onChange={onChange}
          />
          <input
            type="text"
            name="subject"
            value={value["subject"]}
            onChange={onChange}
          />
          <input
            type="text"
            name="body"
            value={value["body"]}
            onChange={onChange}
          />
          >
          <button type="submit" onClick={onSubmit}>
            Save
          </button>
        </form>
      );
    };
    
    export default Form;
    console.log(values);
    

    这是你的解决方案。

    const [fields, setFields] = useState({});
    const [values, setValues] = useState({});
    
    // some fetch logic
    
    // happens on loading some data
    // for example data structure look's like:
    // fetchedData = {
    //   email: 'email@placeholder'
    //   subject: 'subject placeholder'
    //   body: 'body placeholder'
    // }
    useEffect(() => {
      if (fetchedData) {
        setFields(fetchedData)
      }
    }, [fetchedData]);
    
    // happens on fields changed
    useEffect(() => {
      if (fields) {
        setValues(fields)
      }
    }, [fields]);
    
    
    const changedData = (evt) => {
      setValues({ ...values, [evt.target.name]: evt.target.value });
    }
    
    return (
      <div>
        <form onSubmit={submitFunction}>
          {Object.keys(fields).map(_ => (
            <input
              type="text"
              name={_}
              value={values[_]}
              onChange={changedData}
            />
          ))}
          <input type="submit" value="Submit"></input>
        </form>
      </div>
    );
    

    【讨论】:

    • 其实onChange函数根本无法传递事件。所以它给出了'Event.target'是未定义的。确切的错误是--TypeError: undefined is not an object (evalating 'evt.target.name')。我在 onChange 中的函数调用有问题吗?
    • 我会更新我的答案。将onChange 处理程序设置为输入组件。
    • 不,所以我有一个动态创建的表单,也就是说,可能有不同数量的输入文本字段(其值存储为单独的状态变量)。这就是为什么我要遍历每一对,并尝试将其添加到所需的组件中(参见 useEffect)。执行此操作时,onChange 无法将 Event 变量传递给 changedData 函数(显示未定义的目标)。有没有办法像这样动态设置的表单可以有一个 onChange 处理程序?
    • 在我的回答中查看更新。您不需要直接更新 HTML Dom 树。在反应方式中,您需要使用 jsx 构建它。正如您在 render 方法中看到的,我们从 fields 对象构建输入字段
    • 所以 .map() 东西工作得很好!非常感谢您的多次回复和代码编辑以及非常有用的建议! :) 不过,做了一个微小的改变,这可能对可能正在阅读本文的其他人有所帮助。由于在这种情况下 'fields' 是一个对象,并且 .map() 函数仅适用于数组,因此会引发错误。因此,在 Object 字段的键上运行 .map() --Object.keys(fields).map。 @Pavel 再次感谢,多年来一直坚持这一点,非常感谢 :)
    猜你喜欢
    • 1970-01-01
    • 2020-12-16
    • 2020-01-26
    • 2021-05-21
    • 2021-07-11
    • 1970-01-01
    • 1970-01-01
    • 2016-11-06
    • 2018-04-10
    相关资源
    最近更新 更多