You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React子组件向父组件传值时出现Cannot read properties of undefined错误

React子组件向父组件传值时出现Cannot read properties of undefined错误

我尝试将简单值从React子组件传递到父组件,但每次触发父组件传递给子组件的函数时,都会出现错误:Cannot read properties of undefined。我参考了相关示例但未找到问题所在,虽然可以将下拉菜单合并到单个组件中,但希望保持组件分离。

父组件代码

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时会触发该错误。


问题原因

错误出在子组件的props接收方式上。你在子组件中写了function ClassesDropdown({ props }),这是错误的写法——React组件的props是直接传入的参数对象,不存在名为props的属性,因此这里的props变量实际是undefined,调用props.onClassFetch自然会触发Cannot read properties of undefined错误。

修复方案

有两种正确的props接收方式:

  1. 直接解构需要的属性
    修改子组件的定义,直接解构父组件传递的onClassFetch函数:
function ClassesDropdown({ onClassFetch }) {
  const [classList, setClassList] = useState([]);

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

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

  // 其余代码不变
}
  1. 接收完整的props对象
    如果需要用到多个props,可以直接接收整个props对象,不需要解构:
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);
  };

  // 其余代码不变
}

修改后,子组件就能正确调用父组件传递的函数,将选中的class ID传递回父组件更新状态。

内容的提问来源于stack exchange,提问作者Mark_099

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 05:55:24