【问题标题】:Error "Cannot read properties of undefined" while trying to pass data from child to parent component尝试将数据从子组件传递到父组件时出现错误“无法读取未定义的属性”
【发布时间】:2022-11-02 21:23:18
【问题描述】:

我一直在尝试将一个简单的值从子组件传递给父组件,但是每次触发从父组件传递给子组件的函数时,都会出现错误:无法读取未定义的属性。我查看了示例,但看不出有什么问题。我知道一个简单的下拉菜单可以很容易地实现到一个组件中,但我想保持分开。 下面是父组件的代码:

import React, { useState } from "react";
import Axios from "axios";
import "../css/app.css";
import ClassesDropdown from "./ClassesDropdown";

function CreateCharacter() {
  const [name, setName] = useState("");
  const [race, setRace] = useState("");
  const [classId, setClassId] = useState("1");
  const [level, setLevel] = useState("");
  const [creatorId, setCreatorId] = useState("");
  const [campaignId, setCampaignId] = useState("");
  const [description, setDescription] = useState("");

  const submitPost = () => {
    Axios.post("http://localhost:3002/api/characters/create", {
      name: name,
      race: race,
      classId: classId,
      level: level,
      creatorId: creatorId,
      campaignId: campaignId,
      description: description,
    });
  };

  const getClassDropdown = (selectedClass) => {
    setClassId(selectedClass);
    console.log("Class is selected!");
  };

  return (
    <div>
      <div className="boxed">
        <span className="formTitle">Create a character:</span>
        <div>
          <label>Name: </label>
          <input
            type="text"
            onChange={(e) => {
              setName(e.target.value);
            }}
          />
        </div>

        <div>
          <label>Race: </label>
          <input
            type="text"
            onChange={(e) => {
              setRace(e.target.value);
            }}
          />
        </div>

        <div>
          <label>Class: </label>
          <ClassesDropdown onClassFetch={getClassDropdown} />
        </div>

        <div>
          <label>Level: </label>
          <input
            type="number"
            onChange={(e) => {
              setLevel(e.target.value);
            }}
          />
        </div>

        <div>
          <label>Creator:</label>
          <input
            type="number"
            onChange={(e) => {
              setCreatorId(e.target.value);
            }}
          />
        </div>

        <div>
          <label>Campaign: </label>
          <input
            type="number"
            onChange={(e) => {
              setCampaignId(e.target.value);
            }}
          />
        </div>

        <div>
          <label>Description: </label>
          <textarea
            onChange={(e) => {
              setDescription(e.target.value);
            }}
          />
        </div>

        <div>
          <label>Image: </label>
          <input
            type="file"
            onChange={(e) => {
              console.log("Image:", e);
            }}
          />
        </div>

        <button onClick={submitPost}>Create a Character</button>
      </div>
    </div>
  );
}

export default CreateCharacter;

以及子组件的代码:

import React, { useState, useEffect } from "react";
import Axios from "axios";
import "../css/app.css";

function ClassesDropdown({ props }) {
  const [classList, setClassList] = useState([]);

  useEffect(() => {
    Axios.get("http://localhost:3002/api/classes/get").then((data) => {
      console.log(data);
      setClassList(data.data);
    });
  }, []);

  const selectHandler = (e) => {
    props.onClassFetch(e.target.value);
  };

  return (
    <div>
      <select name="classesSelect" onChange={selectHandler}>
        {classList.map((val, key) => {
          return (
            <option key={key} value={val.id}>
              {val.class}
            </option>
          );
        })}
      </select>
    </div>
  );
}

export default ClassesDropdown;

我尝试控制台从下拉菜单中记录选定的值,它得到了正确的值,只是当我尝试执行 props.onClassFetch 时我得到了错误。

【问题讨论】:

  • 什么是完整的错误?通常它有“(读取 xyz)”最后
  • 哦,您在组件中使用 ClassesDropdown({ props }) 解构道具,但应该只使用 ClassesDropdown(props) 而不使用解构

标签: javascript reactjs react-hooks


【解决方案1】:

自从我从事 React 工作以来已经有一分钟了,但问题似乎在于您如何在此处解构 ClassesDropdown 函数参数:

function ClassesDropdown({ props })

因为当组件在父级中创建时,您实际上是在将字典传递给函数,所以您可以删除解构,如下所示:

function ClassesDropdown(props)

另一种选择是继续使用解构,但使解构参数的名称与命名参数一致:

function ClassesDropdown({ onClassFetch }) {

  ...

  const selectHandler = (e) => {
    onClassFetch(e.target.value);
  };

  ...
}

【讨论】:

    【解决方案2】:

    从此更改您的代码

    // ..... above code
    function ClassesDropdown({ props }) {
      const [classList, setClassList] = useState([]);
    
      useEffect(() => {
    
    //..... below code
    

    对此

    // ..... above code
    function ClassesDropdown(props) {
      const [classList, setClassList] = useState([]);
    
      useEffect(() => {
    
    //..... below code
    
    

    【讨论】:

    • 非常感谢它现在有效!
    【解决方案3】:

    从主函数中删除 {} 有效。谢谢大家,我没有看到,谢谢你的解释!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-13
      • 1970-01-01
      • 2018-01-02
      • 1970-01-01
      • 2021-02-22
      • 2019-04-15
      • 2021-03-03
      相关资源
      最近更新 更多