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

React Context返回undefined:子组件状态无法传递至父组件

问题原因分析

你遇到的核心问题是混淆了React Context的传递方向:

  • Context的设计是用来向下传递数据(从父组件到子/孙组件),而不是向上传递给父组件。
  • 你在Form组件内部包裹了peopleContext.Provider,这意味着只有Form组件内部的子组件才能访问到Context的值;而父组件LowerStateChallenge是Form的渲染者,不在Provider的覆盖范围内,所以调用useContext(peopleContext)会返回Context的默认值(undefined,因为createContext()没传入默认值)。
解决方案

根据你的需求,有两种常用的处理方式:

方式1:状态提升到父组件(推荐)

把people状态移到父组件LowerStateChallenge中,通过Props将修改状态的方法传递给Form,同时用Context包裹子组件实现数据向下传递:

修改后的Form组件

import { useState } from "react";

export default function Form({ onAddPerson }) {
  const [name, setName] = useState("");

  const handleSubmit = (e) => {
    e.preventDefault();
    if (!name) {
      alert("Please Provide Name Value");
      return;
    }
    onAddPerson(name);
    setName("");
  };

  return (
    <section>
      <form className="form" onSubmit={handleSubmit}>
        <div className="form-row">
          <label htmlFor="name" className="form-label">
            name
          </label>
          <input
            type="text"
            name="name"
            id="name"
            className="form-input"
            value={name}
            onChange={(e) => setName(e.target.value)}
          />
        </div>
        <button className="btn btn-block" type="submit">
          submit
        </button>
      </form>
    </section>
  );
}

修改后的父组件LowerStateChallenge

import React, { useState, createContext } from 'react';
import List from './List';
import Form from './Form';
import { data } from '../../../../data';

export const PeopleContext = createContext();

const LowerStateChallenge = () => {
  const [people, setPeople] = useState(data);

  const addPerson = (name) => {
    const fakeId = Date.now();
    const newPerson = { id: fakeId, name };
    setPeople([...people, newPerson]);
  };

  // 父组件可直接访问people状态
  console.log(people);

  return (
    <PeopleContext.Provider value={{ people }}>
      <section>
        <Form onAddPerson={addPerson} />
        <List people={people} />
      </section>
    </PeopleContext.Provider>
  );
};

export default LowerStateChallenge;

方式2:通过回调Props向上传递状态

如果坚持要在Form组件内保留people状态,可以通过回调函数将状态传递给父组件:

修改后的Form组件

import { useState } from "react";
import { data } from "../../../../data";

export default function Form({ onPeopleChange }) {
  const [people, setPeople] = useState(data);
  const [name, setName] = useState("");

  const handleSubmit = (e) => {
    e.preventDefault();
    if (!name) {
      alert("Please Provide Name Value");
      return;
    }
    addPerson();
    setName("");
  };

  const addPerson = () => {
    const fakeId = Date.now();
    const newPerson = { id: fakeId, name };
    const newPeople = [...people, newPerson];
    setPeople(newPeople);
    // 调用回调,将新状态传递给父组件
    onPeopleChange(newPeople);
  };

  return (
    <section>
      <form className="form" onSubmit={handleSubmit}>
        <div className="form-row">
          <label htmlFor="name" className="form-label">
            name
          </label>
          <input
            type="text"
            name="name"
            id="name"
            className="form-input"
            value={name}
            onChange={(e) => setName(e.target.value)}
          />
        </div>
        <button className="btn btn-block" type="submit">
          submit
        </button>
      </form>
    </section>
  );
}

修改后的父组件LowerStateChallenge

import React, { useState } from 'react';
import List from './List';
import Form from './Form';

const LowerStateChallenge = () => {
  const [people, setPeople] = useState([]);

  return (
    <section>
      <Form onPeopleChange={setPeople} />
      <List people={people} />
    </section>
  );
};

export default LowerStateChallenge;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 23:55:23