【问题标题】:React error: Cannot read property 'users' of undefined反应错误:无法读取未定义的属性“用户”
【发布时间】:2020-04-03 23:10:58
【问题描述】:

我正在尝试运行此代码(从某个来源获取),其中动态创建输入并在提交时记录值。 我收到此错误:

在调用 createUI 时无法读取未定义的属性“用户”。

有人可以帮我吗?

import React, { useState } from "react";
import ReactDOM from "react-dom";

export default function App() {
  const [state, setState] = useState({
    users: [{ firstName: "", lastName: "" }]
  });

  const addClick = () => {
    setState(prevState => {
      users: [...prevState.users, { firstName: "", lastName: "" }];
    });
  };
  const createUI = () => {
    state.users.map((el, i) => {
      return (
        <div key={i}>
          <input
            placeholder="First Name"
            name="firstName"
            value={el.firstName || ""}
            onChange={handleChange}
          />
          <input
            placeholder="Last Name"
            name="lastName"
            value={el.lastName || ""}
            onChange={handleChange}
          />
          <input type="button" value="remove" onClick={removeClick} />
        </div>
      );
    });
  };

  const handleChange = (i, e) => {
    const { name, value } = e.target;
    let users = [...state.users];
    users[i] = { ...users[i], [name]: value };
    setState({ users });
  };

  const removeClick = i => {
    let users = [...state.users];
    users.splice(i, 1);
    setState({ users });
  };

  const handleSubmit = event => {
    alert("A name was submitted: " + JSON.stringify(this.state.users));
    event.preventDefault();
  };
  return (
    <form onSubmit={handleSubmit}>
      {createUI()}
      <input type="button" value="add more" onClick={addClick()} />
      <input type="submit" value="Submit" />
    </form>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));

// const rootElement = document.getElementById("root");
// ReactDOM.render(<App />, rootElement)

这里是沙盒 -> https://codesandbox.io/s/dynamic-fields-23cw4?fontsize=14&hidenavigation=1&theme=dark

【问题讨论】:

  • 1) onClick={addClick()} 应该是 onClick={addClick}。 2)您需要在addClick 中用() 包装对象。 3)你需要return state.users.map从createUI函数
  • 4) 将onChange 更改为:onChange={e =&gt; handleChange(i, e)} 否则,您将事件作为第一个参数而不是索引
  • 感谢@adiga,也非常感谢大家的热心帮助。

标签: javascript reactjs


【解决方案1】:

您的代码存在 3 个问题,

  1. 您执行了 onclick 处理程序,addClick 触发了无限循环
  2. createUI 方法未返回已创建组件的数组
  3. addClick 函数的 setState 语法不正确。

const {useState} = React;

function App() {
  const [state, setState] = useState({
    users: [{ firstName: "", lastName: "" }]
  });

  const addClick = () => {
    setState(prevState => {
      return { users: [...prevState.users, { firstName: "", lastName: "" }] };
    });
  };
  const createUI = () => {
    return state.users.map((el, i) => {
      return (
        <div key={i}>
          <input
            placeholder="First Name"
            name="firstName"
            value={el.firstName || ""}
            onChange={(e)=>handleChange(e, i)}
          />
          <input
            placeholder="Last Name"
            name="lastName"
            value={el.lastName || ""}
            onChange={(e)=>handleChange(e, i)}
          />
          <input type="button" value="remove" onClick={removeClick} />
        </div>
      );
    });
  };

  const handleChange = (e, i) => {
    const { name, value } = e.target;
    let users = [...state.users];
    users[i] = { ...users[i], [name]: value };
    setState({ users });
  };

  const removeClick = i => {
    let users = [...state.users];
    users.splice(i, 1);
    setState({ users });
  };

  const handleSubmit = event => {
    alert("A name was submitted: " + JSON.stringify(this.state.users));
    event.preventDefault();
  };
  return (
    <form onSubmit={handleSubmit}>
      {createUI()}
      <input type="button" value="add more" onClick={addClick} />
      <input type="submit" value="Submit" />
    </form>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
<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="root"></div>

【讨论】:

  • 无法在您发布的更改的输入框中输入任何值。你能看看吗。
  • @SaurabhSingh:现在检查输入的代码在上面的 sn-p 中是否正常
  • 谢谢,它现在正在处理 onChange 更改。
  • @SaurabhSingh 另一个仅供参考:您还需要更改 onClick={e =&gt; removeClick(i, e)} 否则它将删除错误的索引
【解决方案2】:

错误 1:

如果你返回一个没有返回语句的对象,它应该用括号括起来

const addClick = () => { setState(prevState => ({ users: [...prevState.users, { firstName: "", lastName: "" }]; })); };

错误 2:

缺少返回语句,

const createUI = () => { return state.users.map((el, i) => { return ( <div key={i}> <input placeholder="First Name" name="firstName" value={el.firstName || ""} onChange={handleChange} /> <input placeholder="Last Name" name="lastName" value={el.lastName || ""} onChange={handleChange} /> <input type="button" value="remove" onClick={removeClick} /> </div> ); }); };

错误 3:

onClick 应该有一个函数,但是你设置了一个从addClick 返回的值,即undefined

... <input type="button" value="add more" onClick={addClick} /> ...

【讨论】:

  • 谢谢,它在这里解决了很多问题,但我仍然无法在输入框中输入任何值
【解决方案3】:

除了@norbiial 的答案应该是公认的答案:您的addClick 函数不正确。您的 setState 呼叫没有返回任何内容,这意味着一旦您单击添加按钮,它就会再次中断。

改成这样:

const addClick = () => {
  setState(prevState => ({
    users: [...prevState.users, { firstName: "", lastName: "" }]
  }));
};

createUI 也会出现同样的问题。

【讨论】:

    【解决方案4】:

    该错误的原因是以下行:

    <input type="button" value="add more" onClick={addClick()} />
    

    从技术上讲,您正在调用 addClick 函数,该函数会更改您的 state 对象的值。工作正常的解决方案如下:

    <input type="button" value="add more" onClick={() => addClick()} />
    

    或更短的方式:

    <input type="button" value="add more" onClick={addClick} />
    

    希望对你有帮助!

    【讨论】:

    • onClick={addClick} 应该没问题
    • 还有几个错误。就像 OP 没有从 createUI 函数返回一样。他们在 addClick 中的对象周围没有 () 包装器
    • 谢谢,它有帮助,但现在我的用户界面好像搞砸了。单击“添加更多”时,一切都消失了。这是一个空白屏幕,我希望最初至少有一对输入框,然后可以使用“添加更多”按钮添加更多内容。提交时应显示这些值并发出警报。
    猜你喜欢
    • 2022-07-26
    • 2017-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-22
    • 1970-01-01
    • 2021-12-26
    相关资源
    最近更新 更多