0

0

如何在 React 中正确地在子组件间传递状态数据

聖光之護

聖光之護

发布时间:2026-02-12 14:06:50

|

893人浏览过

|

来源于php中文网

原创

如何在 React 中正确地在子组件间传递状态数据

本文详解 react 中父子组件通信的规范做法,重点解决通过按钮触发 api 请求后将数据从 toolbarelement 传递至 graphelement 的常见错误,涵盖状态管理、props 传递、不可变性原则及 useeffect 协同更新等核心实践。

在 React 中,直接修改传入的 props 对象(如 state.graph_data = ...)是严格禁止的——这不仅违反 React 的不可变性原则,还会导致状态不同步、渲染异常甚至白屏(如你遇到的 Cannot set properties of undefined 错误)。根本原因在于:你传递给子组件的是一个普通 JavaScript 对象字面量 { graph_data: 0 },它并非 React 状态(useState 或 useReducer 创建的响应式状态),不支持动态更新;且 state 在 ToolbarElement 中被解构为 const { state } = props 后,state 并未与 App 中的原始对象保持引用一致,data.lst[0] 此时也尚未赋值(data 是局部 state,异步获取前为空数组),导致 data.lst[0] 为 undefined,进而引发 TypeError。

✅ 正确方案:提升状态(Lifting State Up) + 受控组件模式

将共享数据 graph_data 的声明和更新逻辑统一收归至共同父组件 App,并通过 props 向下传递 当前值更新函数

✅ 修正后的代码结构

App.js(状态管理中心)

一键职达
一键职达

AI全自动批量代投简历软件,自动浏览招聘网站从海量职位中用AI匹配职位并完成投递的全自动操作,真正实现'一键职达'的便捷体验。

下载
import React, { useState } from 'react';

function App() {
  // ✅ 使用 useState 管理可响应式更新的状态
  const [graphData, setGraphData] = useState(0);

  return (
    <div className="App">
      <div className="App-body">
        <div className="toolbar-element" style={{ top: "50px", left: "0px" }}>
          {/* &#9989; &#20256;&#36882;&#24403;&#21069;&#20540; + &#26356;&#26032;&#20989;&#25968; */}
          <ToolbarElement graphData={graphData} setGraphData={setGraphData} />
        </div>
        <div className="graph-element" style={{ top: "50px", right: "0px" }}>
          {/* &#9989; &#20165;&#20256;&#36882;&#24403;&#21069;&#20540;&#65288;&#21482;&#35835;&#65289; */}
          <GraphElement graphData={graphData} />
        </div>
      </div>
    </div>
  );
}

export default App;

ToolbarElement.js(触发数据获取与更新)

import React, { useState } from 'react';

function ToolbarElement({ graphData, setGraphData }) {
  const [loading, setLoading] = useState(false);

  const handleButtonClick = async () => {
    setLoading(true);
    try {
      const res = await fetch("/data");
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const data = await res.json();

      // &#9989; &#36890;&#36807;&#29238;&#32452;&#20214;&#25552;&#20379;&#30340; setter &#23433;&#20840;&#26356;&#26032;&#29366;&#24577;
      if (Array.isArray(data) && data.length > 0) {
        setGraphData(data[0]); // &#9989; &#27491;&#30830;&#65306;&#35302;&#21457; App &#37325;&#28210;&#26579;
      } else {
        setGraphData(null); // &#25110;&#35774;&#40664;&#35748;&#20540;
      }
    } catch (err) {
      console.error("Failed to fetch graph data:", err);
      setGraphData(null);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div style={{ height: '33.33%', backgroundColor: '#F0F0F0' }}>
      <button onClick={handleButtonClick} disabled={loading}>
        {loading ? 'Loading...' : 'Click me!'}
      </button>
    </div>
  );
}

export default ToolbarElement;

GraphElement.js(消费状态)

function GraphElement({ graphData }) {
  // &#9989; &#23433;&#20840;&#28210;&#26579;&#65306;&#22788;&#29702;&#21487;&#33021;&#30340; null/undefined
  return (
    <div style={{ height: '33.33%', backgroundColor: '#E8E8E8' }}>
      <p>{graphData !== null && graphData !== undefined 
          ? String(graphData) 
          : 'No data available'}</p>
    </div>
  );
}

export default GraphElement;

⚠️ 关键注意事项

  • 不要修改 props:props 是只读的,任何直接赋值(如 props.graphData = x)或修改其属性均属反模式。
  • 避免对象字面量传状态:{ graph_data: 0 } 是静态快照,无法响应式更新;必须用 useState / useReducer 创建可变状态。
  • 异步操作需容错:API 返回可能为空、格式不符或失败,务必校验 data 类型与长度,再取 data[0]。
  • 考虑加载与错误状态:实际项目中建议扩展 graphData 为 { value: ..., loading: boolean, error: string | null } 结构,提升用户体验。
  • 进阶替代方案:若组件嵌套深或状态复杂,可选用 Context API 或状态管理库(如 Zustand、Jotai),但对本例而言,Lifting State Up 已是最简、最清晰的解法。

遵循以上实践,即可实现稳定、可维护、符合 React 哲学的跨组件数据流。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

708

2023.08.02

java中boolean的用法
java中boolean的用法

在Java中,boolean是一种基本数据类型,它只有两个可能的值:true和false。boolean类型经常用于条件测试,比如进行比较或者检查某个条件是否满足。想了解更多java中boolean的相关内容,可以阅读本专题下面的文章。

358

2023.11.13

java boolean类型
java boolean类型

本专题整合了java中boolean类型相关教程,阅读专题下面的文章了解更多详细内容。

36

2025.11.30

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

243

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

705

2024.03.01

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

351

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

326

2023.10.25

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

542

2023.09.20

2026春节习俗大全
2026春节习俗大全

本专题整合了2026春节习俗大全,阅读专题下面的文章了解更多详细内容。

189

2026.02.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.9万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1万人学习

React核心原理新老生命周期精讲
React核心原理新老生命周期精讲

共12课时 | 1.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号