简体   繁体   English

TypeError: Cannot read property 'map' of undefined 当我尝试 map 通过从父组件传递到子组件的道具时显示

[英]TypeError: Cannot read property 'map' of undefined is showing when I'm trying to map over the props passed from parent component to child component

I have an issue mapping over a passing prop, from the parent component (App.js) to the child component (Label.js).我在从父组件(App.js)到子组件(Label.js)的传递道具上映射问题。 the terminal showing me a success compiling with warning.终端向我显示编译成功并带有警告。 when i just click the login button in my application, i directly got an alert says: "Cannot read property 'map' of undefined" and after clicking ok, this error is showing: "TypeError: Cannot read property 'map' of undefined is showing when I'm trying to map over the props passed from parent component to child component".当我在我的应用程序中单击登录按钮时,我直接收到一条警报:“无法读取未定义的属性 'map'”,单击确定后,显示此错误:“TypeError: Cannot read property 'map' of undefined is显示当我尝试 map 处理从父组件传递到子组件的道具时”。 I'm new to React hooks, Any help is much appreciated, and excuse the long lines of code.我是 React 钩子的新手,非常感谢任何帮助,请原谅长行代码。 Thank you谢谢

App.js应用程序.js

import Label from "./Label";
import Register from "./Registration";

export default function App() {
  const [add_task_data, setAddTaskData] = useState({
    title: "",
    description: "",
    date: "",
    priority: "",
  });

  const [state, setState] = useState({
    isAuthenticated: false,
  });
  const [login, setLogin] = useState({
    email: "",
    password: "",
  });


  const [todos, setTodos] = useState([]);

  const fetchTodos = () => {
    if (state.isAuthenticated) {
      var myHeaders = new Headers();
      myHeaders.append("Accept", "application/json");
      myHeaders.append(
        "Authorization",
        `Bearer ${localStorage.getItem("access_token")}`
      );

      var requestOptions = {
        method: "GET",
        headers: myHeaders,
        redirect: "follow",
      };

      fetch("https://codeminos-todo.tk/api/v1/to-dos", requestOptions)
        .then((response) => response.text())
        .then((json) => {
          const result = JSON.parse(json);
          setTodos(result.data);
        })
        .catch((error) => console.log("error", error));
    }
  };
  
  // const checkUserAuth = () => {
    if (state.isAuthenticated) {
      var myHeaders = new Headers();
      myHeaders.append("Accept", "application/json");
      myHeaders.append(
        "Authorization",
        `Bearer ${localStorage.getItem("access_token")}`
      );

      var requestOptions = {
        method: "GET",
        headers: myHeaders,
        redirect: "follow",
      };

      fetch("https://codeminos-todo.tk/api/v1/labels", requestOptions)
        .then((response) => response.text())
        .then((json) => {
          setState({
            isAuthenticated: true,
          });
        })
        .catch((error) => {
          setState({
            isAuthenticated: false,
          });
        });
    }
  // };

  // const fetchLabels = () => {
  //   if (state.isAuthenticated) {
  //     var myHeaders = new Headers();
  //     myHeaders.append("Accept", "application/json");
  //     myHeaders.append(
  //       "Authorization",
  //       `Bearer ${localStorage.getItem("access_token")}`
  //     );

  //     var requestOptions = {
  //       method: "GET",
  //       headers: myHeaders,
  //       redirect: "follow",
  //     };


  //   }
  // };
  
  // useEffect(() => {
  //   fetchTodos();
  //   // fetchLabels();
  // }, [state.isAuthenticated]);
  
  function handleChange(key, value) {
    setAddTaskData({
      ...add_task_data,
      [key]: value,
    });
  }
  function hanldeLoginChange(key, value) {
    setLogin({
      ...login,
      [key]: value,
    });
  }
  const handleLoginSubmit = (event) => {
    event.preventDefault();
    var myHeaders = new Headers();
    myHeaders.append("Accept", "application/json");
    myHeaders.append("Content-Type", "application/x-www-form-urlencoded");

    var urlencoded = new URLSearchParams();
    urlencoded.append("email", "pas2ss@gmail.com2");
    urlencoded.append("password", "212312322");

    var requestOptions = {
      method: "POST",
      headers: myHeaders,
      body: urlencoded,
    };

    fetch("https://codeminos-todo.tk/api/login",requestOptions) 
     
      .then((response) => {
        return response.json();
      })
      .then((data) => {
        if (data.access_token !== undefined) {
          localStorage.setItem("access_token", data.access_token);
          setState({
            ...state,
            isAuthenticated: true,
          });
        }
      })
      .catch((error) => {
        alert(error.message);
      });
  };

  const handleAddToDoSubmit = (event) => {
    event.preventDefault();
    var myHeaders = new Headers();
    myHeaders.append("Accept", "application/json");
    myHeaders.append(
      "Authorization",
      `Bearer ${localStorage.getItem("access_token")}`
    );
    myHeaders.append("Content-Type", "application/x-www-form-urlencoded");

    var urlencoded = new URLSearchParams();
    urlencoded.append("title", add_task_data.title);
    urlencoded.append("description", add_task_data.description);
    urlencoded.append("priority", add_task_data.priority);
    urlencoded.append("date", add_task_data.date);

    var requestOptions = {
      method: "POST",
      headers: myHeaders,
      body: urlencoded,
      redirect: "follow",
    };

    fetch("https://codeminos-todo.tk/api/v1/to-dos", requestOptions)
      .then((response) => response.text())
      .then((result) => {
        fetchTodos();
      })
      .catch((error) => console.log("error", error));
  };
  
  
  return (
    <>
      <div>
        <Register /> <br/>
        
        <br/>
      </div>
      <div className="App">
        <h2>Welcome to your task manager app</h2>

        {!state.isAuthenticated && (
          <div>
            <h2>You are not authenticated, please login</h2>

            <form onSubmit={(event) => handleLoginSubmit(event)}>
              <div>
                <label>Email: </label>
                <input
                  type="text"
                  name="email"
                  onChange={(event) => {
                    hanldeLoginChange("email", event.target.value);
                  }}
                />
              </div>
              <div>
                <label>password</label>

                <input
                  type="text"
                  name="password"
                  onChange={(event) => {
                    hanldeLoginChange("password", event.target.value);
                  }}
                />
              </div>
              <input type="submit" value="login" />
            </form>
          </div>
        )}
        {state.isAuthenticated && (
          <div>
            <h2>Tasks</h2>
            {todos.map((todo) => {
              return (
                <div>
                  Title {todo.title} --- description: {todo.description}
                </div>
              );
            })}

            
            <button
              onClick={() => {
                setState({
                  ...state,
                  isAuthenticated: false,
                });
                localStorage.removeItem("access_token");
              }}
            >
              Logout
            </button>
            <h2>Add TODO</h2>
            <form
              onSubmit={(event) => {
                handleAddToDoSubmit(event);
              }}
            >
              <div>
                <label>Title</label>
                <input
                  type="text"
                  name="title"
                  onChange={(event) => {
                    handleChange("title", event.target.value);
                  }}
                />
              </div>
              <div>
                <label>description</label>

                <input
                  type="text"
                  name="description"
                  onChange={(event) => {
                    handleChange("description", event.target.value);
                  }}
                />
              </div>
              <div>
                <label>date</label>

                <input
                  type="text"
                  name="date"
                  onChange={(event) => {
                    handleChange("date", event.target.value);
                  }}
                />
              </div>
              <div>
                <label>priority</label>
                <input
                  type="text"
                  name="priority"
                  onChange={(event) => {
                    handleChange("priority", event.target.value);
                  }}
                />
              </div>
              
              <Label {...add_task_data.title}/>
              
              <input type="submit" value="add todo" />
            </form>
            {JSON.stringify(add_task_data)}
          </div>
        )}
      </div>
    </>
  );
}

Label.js Label.js


export default function Label(props){
  const [labels, setLabels] = useState({ label: "" });
   const [state, setState] = useState({
     isAuthenticated: false,
   });

  function handleChangeLabel(key, value) {
    setLabels({
      ...labels,
      [key]: value,
    });
  }

     if (state.isAuthenticated) {
      const handleSubmitLabel = (event) => {
        event.preventDefault();

        var myHeaders = new Headers();
        myHeaders.append(
          "Authorization",
          `Bearer ${localStorage.getItem("access_token")}`
        );
        myHeaders.append("Content-Type", "application/x-www-form-urlencoded");

        var urlencoded = new URLSearchParams();
        urlencoded.append("name", labels.label);

        var requestOptions = {
          method: "POST",
          headers: myHeaders,
          body: urlencoded,
          redirect: "follow",
        };

        fetch("https://codeminos-todo.tk/api/v1/labels", requestOptions)
          .then((response) => response.text())
          .then((json) => {
            const result = JSON.parse(json);
            setLabels(result.data);
             setState({
               isAuthenticated: true,
             });
          })
          .catch((error) => {
            setState({
               isAuthenticated: false,
             });
          });
      };
     }
  

  return (
    <>
      <form onSubmit={(event) => {handleSubmitLabel(event)}}>
        <span>
          <label>Add a Label to your task</label>
          
          {props.add_task_data.map(task => {
           <select onChange={handleChangeLabel} name="task-label">
             <option>{task}</option>
           </select>
          })}
         
        </span>
      </form>
      </>
  );       
      

  
  
}

In parent when you are passing data to child, you are passing <Label {...add_task_data.title}/> which means you are passing only title but in child class you are trying to map whole data which you don't have.在父级中,当您将数据传递给子级时,您正在传递<Label {...add_task_data.title}/>这意味着您仅传递标题,但在子级 class 中,您正在尝试 map 您没有的整个数据。 so instead pass whole of the dataset like <Label {add_task_data}/> .所以改为传递整个数据集,如<Label {add_task_data}/>

The issue is that you are expecting, in Label.js , the prop add_task_data when you try to access to it:问题是您期望在Label.js中,当您尝试访问道具add_task_data时:

export default function Label(props){
  
  // ...

  return (
    // ...
          // will throw when "add_task_data" prop value is *undefined*
          {props.add_task_data.map(task => {
             // ...
          })}
    // ...
  );
}

Then, in App.js, when you instantiate the component:然后,在 App.js 中,当您实例化组件时:

              <Label {...add_task_data.title}/>

you are not passing the add_task_data expected prop.您没有通过add_task_data预期道具。 In this case, you are deconstructing the spread of add_task_data.在这种情况下,您正在解构 add_task_data 的传播。 title which is a string , which doesn't seem to be making sense for your current scenario. title是一个string ,这对于您当前的情况似乎没有意义。

A solution to your issue, which I believe is what you were intending to do, would be just instantiating Label as:我相信您打算这样做的解决您的问题的方法是将 Label 实例化为:

              <Label {...add_task_data}/>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 尝试将 map 输出 state 并将其作为道具传递给组件时,“无法读取未定义的属性‘映射’” - “Cannot read property 'map' of undefined” when trying to map out state and pass it as props into component TypeError:尝试读取通过props传递的数组时,无法读取未定义的属性“ map” - TypeError: Cannot read property 'map' of undefined, while trying to .map() an array passed through props 尝试 map 我的道具时,我收到无法读取未定义错误的“练习”属性 - I'm getting a Cannot read property of 'exercises' of undefined error when trying to map my props 执行 map 的父组件传递的道具未定义 - Props passed by a parent component doing a map are undefined 'TypeError: Cannot read property of x of undefined' 将数据从父组件传递到子组件但其他组件正在工作 - 'TypeError: Cannot read property of x of undefined' when passing data from parent to child component but others are working TypeError:无法将子组件中未定义的属性“setState”读取到父组件 - TypeError: Cannot read property 'setState' of undefined in child to parent component 填充react组件会导致“ TypeError:无法读取未定义的属性&#39;map&#39;” - Populating react component results in “TypeError: Cannot read property 'map' of undefined” 类型错误:无法读取反应组件中未定义的属性“映射” - TypeError: Cannot read property 'map' of undefined in react component 未捕获到的TypeError:无法读取ReactJs中{Component} .render上未定义的属性“ map” - Uncaught TypeError: Cannot read property 'map' of undefined at {Component}.render in ReactJs TypeError:无法读取未定义的React组件的属性“ map” - TypeError: Cannot read property 'map' of undefined react component
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM