React 09

1 组件返回它们的 JSX

保持组件纯粹 -- React 中文文档https://zh-hans.react.dev/learn/keeping-components-pure

在 React 等基于 JSX 的前端框架中,"组件返回它们的 JSX" 指的是:组件作为一个函数或类,其核心职责是根据输入的 props 和自身状态(state),计算并返回一段 JSX 结构,这段结构描述了该组件在页面上应该如何渲染。

简单来说,JSX 是一种类似 HTML 的语法扩展,用于描述 UI 结构(比如 <div>Hello</div>)。组件的作用就是 "产出" 这段描述性的 JSX,框架(如 React)会根据这段 JSX 最终渲染出真实的 DOM 元素。

举个例子:

一个简单的函数组件:

javascript 复制代码
function Greeting(props) {
  // 组件的核心逻辑:根据 props 计算并返回 JSX
  return <h1>Hello, {props.name}!</h1>;
}

这里的 return <h1>...</h1> 就是 "组件返回 JSX"------ 它告诉框架:"我需要渲染一个 <h1> 标签,内容是 Hello, [name]!"。

为什么强调 "只返回 JSX,不修改已有对象 / 变量"?

这是为了保证组件的 "纯粹性"(纯函数特性):

  • 纯函数的核心特点是:输入相同,输出一定相同,且不会产生副作用(比如修改外部变量、修改传入的 props 对象等)。
  • 如果组件在返回 JSX 之外,还偷偷修改了外部变量或已有对象(比如修改全局变量、修改父组件传入的 props),就会导致组件行为不可预测,难以调试(比如多次渲染结果不一致,或其他组件受意外影响)。

例如,下面的组件就是 "不纯粹" 的,因为它修改了外部变量:

javascript 复制代码
let globalCount = 0;

function BadComponent() {
  globalCount++; // 副作用:修改了外部变量
  return <div>Count: {globalCount}</div>;
}

这个组件每次渲染都会改变 globalCount,导致多次渲染的结果依赖于渲染次数,而不是输入的 props/state,违背了纯函数原则。

总结:"组件返回 JSX" 是指组件的核心职责是产出描述 UI 的结构,而不是去修改外部状态或已有对象,这样才能保证组件的可预测性和可维护性。

严格模式

这是关于React 严格模式检测不纯计算的说明内容,可从以下几点解读:

1. 渲染输入的只读性

在 React 渲染时,propsstatecontext 这三种输入应视为只读,不能在渲染过程中直接修改。若需更改内容,需通过 "设置状态" 的方式,而非直接写入变量。

2. 严格模式的作用

React 的严格模式(<React.StrictMode>)会在开发时重复调用组件函数两次,以此检测违反 "纯函数" 规则的组件(即那些在渲染时修改预先存在的变量或对象的组件)。它仅在开发环境生效,不会影响生产环境的性能。

3. 纯函数的体现

纯函数组件的特点是 "相同输入总是返回相同输出,且无副作用"。例如文中的纯函数版本,即使被调用两次,结果也不会出错,就像数学函数 double(2)y = 2x 多次计算结果始终一致。

2 局部 mutation(局部可变操作)

在 React 等前端开发语境中,"局部 mutation(局部可变操作)" 指的是在组件内部对仅属于自身的变量进行修改,且这种修改不会影响组件外部的状态或其他组件。它的作用可以从以下几点理解:

1. 用于组件内部的临时状态管理

当组件需要一些 "临时、仅自己用" 的状态时,局部 mutation 可以派上用场。比如:

javascript 复制代码
function MyComponent() {
  // 局部变量,仅在组件内部生效,修改它属于局部 mutation
  let localCount = 0; 
  const handleClick = () => {
    localCount++; // 局部 mutation,只改变组件内部的这个变量
    console.log(localCount);
  };
  return <button onClick={handleClick}>点击</button>;
}

这里的 localCount 是组件内部的临时变量,修改它不会影响外部,可用于记录一些不需要 "跨渲染保存" 的临时状态(比如单次交互中的中间值)。

2. 优化性能(避免不必要的重渲染)

对于一些不需要触发组件重渲染的操作,局部 mutation 可以避免因状态变更导致的性能损耗。例如,组件内部的缓存计算、临时数据的组装:

javascript 复制代码
function DataList({ items }) {
  // 局部变量,用于缓存过滤后的结果
  let filteredItems = []; 
  const filterData = (keyword) => {
    filteredItems = items.filter(item => item.includes(keyword)); // 局部 mutation
    // 后续直接使用 filteredItems,无需触发组件重渲染
  };
  // ...
}

这里修改 filteredItems 是局部操作,不会让组件重新渲染,适合处理那些不需要界面响应的内部逻辑。

3. 区分 "纯渲染" 与 "副作用"

React 要求组件的渲染逻辑(返回 JSX 的过程)必须是纯函数(无副作用、不修改外部状态),但组件内部的 "非渲染逻辑"(如事件处理函数、 useEffect 中的逻辑)可以包含局部 mutation。这样既保证了渲染的可预测性,又能在组件内部灵活处理业务逻辑。

简单来说,"局部 mutation" 就像组件的 "内部小秘密"------ 只在自己的 "地盘" 里折腾,不对外界造成影响,从而在保证组件纯度的前提下,满足内部临时状态管理、性能优化等需求。

【会导致渲染结果是随机的吗?】

"局部 mutation" 虽然是组件内部的 "小秘密",但只要控制在**"仅作用于组件内部、不影响渲染逻辑" 的范围**内,就不会导致渲染结果随机。

它的使用是有明确场景和约束的,我们可以从两个角度理解:

一、局部 mutation 不会让渲染随机的原因

React 组件的渲染结果由 propsstatecontext 决定 (这三者是 "渲染的输入",必须保持只读)。而局部 mutation 操作的是组件内部的 "临时变量",这些变量不会参与 JSX 的渲染计算,所以不会影响最终的 UI 输出。

举个例子:

javascript 复制代码
function Timer() {
  // 局部变量,用于内部计时(属于局部 mutation)
  let localTimer = 0; 
  useEffect(() => {
    const interval = setInterval(() => {
      localTimer++; // 局部 mutation,只改内部变量
      console.log('内部计时:', localTimer);
    }, 1000);
    return () => clearInterval(interval);
  }, []);
  // 渲染的 JSX 只依赖"无 mutation"的结构,所以渲染结果是稳定的
  return <div>我是一个定时器组件</div>;
}

这里 localTimer 的修改是局部的,既不影响 JSX 渲染,也不触发组件重渲染,所以渲染结果始终是 "我是一个定时器组件",完全可预测。

二、局部 mutation 的安全使用场景(保证不影响渲染)

它的 "能干啥" 是很明确的,只要遵循以下场景,就不会有随机性:

  1. 临时状态: 存储组件内部的临时中间值(如单次交互的临时标记、未提交的表单草稿)。
  2. 性能优化: 缓存计算结果、组装临时数据(如过滤列表时的中间结果,不需要界面实时响应)。
  3. 副作用逻辑:useEffect、事件处理函数等 "非渲染逻辑" 中,处理仅组件内部需要的操作(如日志记录、第三方库的局部配置)。

总结一下:只要你把 "局部 mutation" 限定在 "组件内部的非渲染逻辑" 中,它就只是一个 "可控的内部操作",不会让渲染结果随机。

3 React侧重纯函数

4 如何判断一个组件是否是"纯粹"的?

判断一个 React 组件是否 "纯粹",核心是看它是否满足**"输入确定则输出唯一,且无副作用"**的原则。可以通过以下 3 个关键标准逐层验证,确保判断逻辑清晰且全面。


核心判断标准

1. 输入依赖仅为 propsstatecontext

组件的所有渲染逻辑、计算逻辑,只能依赖这三类 "官方输入源",不能依赖外部变量、全局状态、随机值等不可控因素。

  • 符合要求的情况
    • 基于 props.name 拼接字符串。
    • 根据 state.count 计算 count * 2
    • 通过 useContext 获取主题色并应用到样式。
  • 不符合要求的情况
    • 依赖组件外部定义的 let globalNum = 10 进行计算。
    • 使用 Math.random() 生成渲染内容(输入固定时输出随机)。
    • 读取 window.innerWidth 等浏览器全局变量(组件外环境变化会影响输出)。
2. 无 "副作用" 操作

组件在执行过程中(包括渲染阶段、计算阶段),不能修改任何外部状态或自身输入源,也不能执行影响外部环境的操作。

  • 需规避的 "副作用" 行为
    • 修改传入的 props(如 props.name = "newName")。
    • 修改组件外部的变量或对象(如全局数组 window.list.push(1))。
    • 在渲染阶段执行 fetch 请求、操作 DOM、修改 document.title 等。
    • 直接修改 state(如 this.state.count++,需通过 setStateuseState 的更新函数)。
3. 输入相同则输出(JSX)必然唯一

只要 propsstatecontext 这三类输入完全一致,组件返回的 JSX 结构、触发的逻辑就必须完全相同,不存在 "同输入不同输出" 的情况。

  • 符合要求的情况
    • 输入 props.isShow = true 时,始终渲染 <div>显示内容</div>
    • 输入 state.num = 5 时,计算结果 num * 3 始终为 15。
  • 不符合要求的情况
    • 组件内部用 let localNum = 0 记录次数,每次渲染 localNum++ 后嵌入 JSX(同输入下,多次渲染结果不同)。
    • Date.now() 生成时间戳并嵌入 JSX(即使输入相同,不同时间渲染结果不同)。

快速验证方法:"两次渲染测试"

可以模拟 React 严格模式的逻辑,通过 "同一输入下执行两次组件" 来验证纯粹性:

  1. 固定一组 propsstate 作为输入。
  2. 连续两次调用组件函数,观察返回的 JSX 及执行过程。
  3. 若两次结果完全一致,且无外部状态被修改,则组件是纯粹的;反之则不纯粹。

示例验证

javascript 复制代码
// 纯粹组件
function PureComponent({ num }) {
  const double = num * 2;
  return <div>{double}</div>;
}
// 两次输入 num=3,均返回 <div>6</div> → 纯粹

// 不纯粹组件
let localCount = 0;
function ImpureComponent() {
  localCount++;
  return <div>{localCount}</div>;
}
// 两次调用,分别返回 <div>1</div>、<div>2</div> → 不纯粹

总结

判断组件是否纯粹,本质是看它是否 "可控、可预测"。只要满足 **"依赖输入唯一、无副作用、输出确定"** 这三个标准,就是纯粹组件。这类组件更易于调试、复用,也能更好地配合 React 的性能优化机制(如 React.memo)。

5 优化纯粹的组件

javascript 复制代码
export default function Clock({ time }) {
  const hours = time.getHours();
  if (hours >= 0 && hours <= 6) {
    document.getElementById('time').className = 'night';
  } else {
    document.getElementById('time').className = 'day';
  }
  return (
    <h1 id="time">
      {time.toLocaleTimeString()}
    </h1>
  );
}

【document.getElementById('time').className = 'day'; 原本这个想表达什么?】

这句代码的核心意图是给页面中 id 为 "time" 的 DOM 元素,设置一个名为 "day" 的 CSS 类名,本质是通过原生 JavaScript 手动操作 DOM 来控制元素的样式。

代码意图拆解

  1. 获取目标 DOM 元素document.getElementById('time')这部分代码的作用是从整个文档(document)中,找到并获取 id 属性值为 "time" 的 DOM 元素。在你之前的 Clock 组件里,目标就是返回的 <h1 id="time"> 这个标题元素。

  2. 设置 CSS 类名.className = 'day'这部分是给获取到的 DOM 元素赋值,将其 className 属性(对应 HTML 中的 class 属性)设置为 "day"。

    • 前端开发中,className 的核心用途是关联 CSS 样式。当元素拥有 "day" 类名后,会自动应用 CSS 中预先定义的 .day 选择器对应的样式(比如设置字体颜色、背景色等,以体现 "白天" 相关的视觉效果)。
  3. 结合组件逻辑的完整意图 结合你之前 Clock 组件的逻辑,这句代码是想根据时间判断,手动给时钟元素切换 "白天" 样式

    • 当时间不在凌晨 0-6 点时,通过该代码给 id="time" 的元素加 "day" 类,让元素显示白天的样式;
    • 反之则加 "night" 类,显示夜晚的样式。

为什么在 React 组件中不推荐这么写

React 的设计理念是**"声明式" 管理 UI**,即开发者只需通过 JSX 描述 "想要的 UI 是什么样",由 React 内部负责 DOM 的创建和修改,无需手动操作 DOM。

  • 手动用 document.getElementById 操作 DOM,会绕过 React 对 DOM 的管理,可能导致 React 维护的组件状态与实际 DOM 状态不一致(比如样式混乱、重复修改等)。
  • 更合理的方式是像优化后的代码那样,通过计算得到 className,再通过 JSX 的 className 属性绑定到元素上,让 React 统一控制样式,既符合组件纯粹性要求,也更安全可靠。

分析并优化

这个 Clock 组件不是纯粹的组件,核心问题在于它在渲染阶段直接操作了 DOM,违反了 React 组件 "无副作用" 的纯粹性原则。

一、组件不纯粹的核心原因

1. 渲染阶段存在 "副作用" 操作

组件在执行过程中(return 之前)调用了 document.getElementById('time').className = 'xxx'这属于直接操作 DOM 的 "副作用" 行为

  • React 要求渲染阶段(组件函数执行过程)必须是纯函数,只能进行计算、判断等无副作用操作,不能修改 DOM、发送请求、修改外部变量等。
  • 该组件在渲染时直接操作尚未完全挂载的 DOM 元素,不仅破坏纯粹性,还可能因 DOM 未渲染完成导致 getElementById 获取到 null,引发报错。
2. 逻辑与 React 渲染机制冲突

React 组件的 UI 应由 JSX 描述,样式应通过 JSX 中的 className 属性绑定,而非手动操作 DOM。

  • 组件的 return 已经返回了 <h1 id="time">,但又在渲染前手动修改该元素的类名,相当于 "重复操作",违背了 React 对 UI 的统一管理逻辑。
  • 若组件因 time 变化重新渲染,手动修改的类名可能与 JSX 描述的状态不一致,导致样式混乱。

二、优化方案:改造为纯粹组件

要让组件恢复纯粹性,需移除渲染阶段的副作用,通过 React 原生方式绑定样式。优化后的代码如下:

javascript 复制代码
export default function Clock({ time }) {
  const hours = time.getHours();
  // 1. 仅通过计算得到 className,无副作用操作
  const className = hours >= 0 && hours <= 6 ? 'night' : 'day';
  
  // 2. 通过 JSX 的 className 属性绑定样式,由 React 统一管理 DOM
  return (
    <h1 id="time" className={className}>
      {time.toLocaleTimeString()}
    </h1>
  );
}

三、优化后组件的纯粹性验证

  1. 输入依赖唯一 :仅依赖传入的 props.time,无其他外部依赖。
  2. 无副作用 :渲染过程中仅计算 className,未修改 DOM、外部变量等,符合纯函数要求。
  3. 输入输出确定 :只要 time 相同,hours 计算结果就相同,className 和返回的 JSX 也完全一致,输出唯一可预测。

四、关键结论

React 组件的纯粹性核心是 "渲染阶段只做计算,不做修改"。UI 相关的状态(如样式、结构)应通过 "计算结果 → 嵌入 JSX" 的方式由 React 统一渲染,而非手动操作 DOM 破坏这一流程。

6 什么是DOM

DOM 是 Document Object Model(文档对象模型) 的缩写,它是浏览器将 HTML/XML 文档解析后生成的树形结构对象模型,本质是一套让程序(如 JavaScript)能访问、操作网页内容和结构的接口。

简单说,DOM 把网页的 HTML 结构 "翻译" 成 JavaScript 能看懂的 "对象",让你可以通过代码修改网页的内容、样式和结构。

一、DOM 的核心作用:连接 HTML 与 JavaScript

浏览器加载 HTML 后,会自动将 HTML 标签转化为 DOM 树中的节点(Node),每个节点对应一个 HTML 元素、属性或文本。

举个例子:

一段简单的 HTML 代码:

html 复制代码
<!DOCTYPE html>
<html>
  <body>
    <h1 id="time" class="day">12:00:00</h1>
  </body>
</html>

浏览器解析后生成的 DOM 树结构(简化):

  • document(根对象,代表整个文档)
    • html 节点(根元素节点)
      • body 节点(子元素节点)
        • h1 节点(子元素节点)
          • 属性节点:id="time"class="day"
          • 文本节点:12:00:00

通过 DOM 接口,JavaScript 就能 "找到" 并 "操作" 这个 h1 节点,比如修改它的文本、样式或属性。

二、DOM 的常见操作(通过 JavaScript 实现)

开发者主要通过 document 对象提供的方法操作 DOM,核心操作可分为四类:

操作类型 常见方法示例 作用说明
查找节点 document.getElementById('time') 根据 id 找到指定元素节点
document.querySelector('.day') 根据 CSS 选择器找到第一个匹配的元素节点
修改内容 element.textContent = '13:00:00' 修改元素的文本内容
element.innerHTML = '<span>13:00</span>' 修改元素内部的 HTML 结构
修改样式 element.className = 'night' 修改元素的 CSS 类名
element.style.color = 'white' 直接修改元素的行内样式
修改结构 document.createElement('div') 创建一个新的元素节点
parent.appendChild(child) 给父节点添加子节点(插入元素)
parent.removeChild(child) 从父节点中删除子节点(移除元素)

三、DOM 与 React 的关系

React 的核心设计理念之一是 **"虚拟 DOM(Virtual DOM)"**,它是对真实 DOM 的 "轻量副本"。

  1. React 为何不推荐直接操作真实 DOM?

    • 真实 DOM 操作性能开销大,频繁修改可能导致页面卡顿。
    • 直接操作 DOM 会绕过 React 对页面状态的管理,容易出现 "React 状态与真实 DOM 不一致" 的问题(比如你之前组件中手动修改 className 的情况)。
  2. React 的处理方式

    • 开发者通过 JSX 描述 UI 结构,React 内部将其转化为虚拟 DOM。
    • 当数据(props/state)变化时,React 会对比新旧虚拟 DOM 的差异,只更新真实 DOM 中需要变化的部分,既保证了 UI 与状态一致,又优化了性能。

总结

DOM 是浏览器提供的 "桥梁",让 JavaScript 能操作网页;而 React 则通过虚拟 DOM 对真实 DOM 操作进行了 "优化和封装",让开发者更专注于数据和 UI 的关系,无需手动频繁操作真实 DOM。

DOM 核心概念、操作方法,以及与 React 实现方式的对比表

一、DOM 核心概念

概念 说明
定义 Document Object Model(文档对象模型),浏览器将 HTML 解析为树形结构的对象模型,供程序(如 JS)操作。
本质 一套接口(API),连接 HTML 与 JavaScript,使 JS 能修改网页内容、样式、结构。
核心结构 document 为根的树形节点结构,每个节点对应 HTML 元素、属性或文本。
与 React 的关系 React 通过 "虚拟 DOM(Virtual DOM)" 间接操作真实 DOM,优化性能并统一状态管理。

二、常见 DOM 操作及 React 对应实现

操作类型 原生 DOM 操作(JavaScript) React 实现方式(JSX + Hooks) 核心差异
查找元素 document.getElementById('id') 无需手动查找,通过 JSX 直接绑定数据(或用 ref 特殊场景) React 中 UI 由数据驱动,无需手动获取 DOM 元素,ref 仅用于极少数必须操作 DOM 的场景(如聚焦输入框)。
document.querySelector('.class')
修改文本 element.textContent = '新内容' <div>{变量}</div>(变量更新时自动渲染) React 通过 "数据变化 → 重新渲染 JSX" 实现文本更新,无需手动操作 DOM。
修改样式 element.className = 'active'(类名) <div className={条件 ? 'active' : ''}> React 将样式类名通过 JSX 属性绑定,由 React 自动同步到 DOM。
element.style.color = 'red'(行内样式) <div style={``{ color: 'red' }}> React 行内样式需用对象形式(驼峰命名,如 fontSize),而非字符串。
修改结构 document.createElement('div')(创建元素) 直接在 JSX 中写元素,如 <div>新内容</div> React 中 UI 结构由 JSX 声明式描述,无需手动创建 / 插入 DOM 节点。
parent.appendChild(child)(添加子元素) 用数组渲染列表:{list.map(item => <li key={item.id}>{item}</li>)} React 通过数组 map 生成列表,自动处理 DOM 增删,需加 key 优化性能。
element.remove()(删除元素) 用条件渲染:{show && <div>显示内容</div>} React 通过布尔值控制元素是否渲染,无需手动删除 DOM。
事件绑定 element.addEventListener('click', handleClick) <button onClick={handleClick}> React 事件用驼峰命名(如 onClick),直接绑定函数,无需手动添加 / 移除监听器。

三、关键结论

  1. DOM 是浏览器提供的原生接口,允许直接操作网页元素,但手动操作繁琐且可能导致性能问题。
  2. React 封装了 DOM 操作,通过 "数据驱动 + 声明式 JSX" 让开发者专注于 "UI 应该是什么样",而非 "如何操作 DOM 实现"。
  3. 开发 React 时,应优先使用 React 提供的方式(如状态管理、条件渲染、样式绑定),避免直接调用 document 相关 API 操作 DOM,否则可能破坏组件纯粹性和状态一致性。

7 不纯粹的组件改错

javascript 复制代码
import Panel from './Panel.js';
import { getImageUrl } from './utils.js';

let currentPerson;

export default function Profile({ person }) {
  currentPerson = person;
  return (
    <Panel>
      <Header />
      <Avatar />
    </Panel>
  )
}

function Header() {
  return <h1>{currentPerson.name}</h1>;
}

function Avatar() {
  return (
    <img
      className="avatar"
      src={getImageUrl(currentPerson)}
      alt={currentPerson.name}
      width={50}
      height={50}
    />
  );
}

这个组件不是纯粹的 ,核心问题在于它通过全局变量 currentPerson 在组件间传递数据,违反了 React 组件 "依赖输入唯一、无副作用" 的纯粹性原则,可能导致不可预测的渲染结果。

一、组件不纯粹的具体原因

1. 存在 "副作用":修改外部全局变量

Profile 组件在渲染过程中执行了 currentPerson = person,这是对组件外部定义的 let currentPerson 进行修改,属于副作用操作 。React 要求组件渲染阶段(函数执行过程)只能做计算,不能修改外部状态(包括全局变量、父组件传入的 props 等),否则会破坏组件的可预测性。

2. 依赖非标准输入源:全局变量

HeaderAvatar 组件没有通过 props 接收数据,而是直接依赖全局变量 currentPerson 渲染内容。这会导致:

  • 组件的输入来源不明确(无法通过函数参数看出依赖什么数据)。
  • currentPerson 被其他代码意外修改(比如其他组件也操作这个变量),HeaderAvatar 的渲染结果会突然变化,难以调试。
3. 同输入可能不同输出:违反确定性

假设 Profile 组件因父组件更新而重新渲染,即使传入的 person 相同,currentPerson 也会被重复赋值(虽然值没变,但逻辑上仍属于不必要的副作用)。更严重的是:如果 React 在严格模式下对组件进行 "双重渲染"(开发环境检测不纯组件的机制),可能会导致 currentPerson 状态混乱,最终 HeaderAvatar 渲染出错误内容。

二、优化方案:通过 props 传递数据(改造为纯粹组件)

React 中组件间传递数据的标准方式是 props,它能保证数据流向清晰、组件依赖明确。优化后的代码如下:

javascript 复制代码
import Panel from './Panel.js';
import { getImageUrl } from './utils.js';

// 移除全局变量 currentPerson

export default function Profile({ person }) {
  // 不再修改外部变量,仅通过 props 向下传递数据
  return (
    <Panel>
      <Header name={person.name} />  {/* 通过 props 传值给 Header */}
      <Avatar person={person} />     {/* 通过 props 传值给 Avatar */}
    </Panel>
  );
}

// Header 仅依赖自身 props,不依赖外部变量
function Header({ name }) {
  return <h1>{name}</h1>;
}

// Avatar 仅依赖自身 props,不依赖外部变量
function Avatar({ person }) {
  return (
    <img
      className="avatar"
      src={getImageUrl(person)}
      alt={person.name}
      width={50}
      height={50}
    />
  );
}

三、优化后组件的纯粹性验证

  1. 输入依赖唯一

    • Profile 仅依赖传入的 props.person
    • Header 仅依赖 props.nameAvatar 仅依赖 props.person。所有组件的渲染逻辑都基于明确的 props,无全局变量依赖。
  2. 无副作用:渲染过程中仅做数据传递和计算,不修改任何外部变量或对象,符合纯函数要求。

  3. 输入输出确定 :只要传入的 person 相同,Profile 传递给子组件的 props 就相同,HeaderAvatar 返回的 JSX 也必然一致,输出完全可预测。

四、关键结论

React 组件间的数据传递应遵循**"单向数据流"** 原则:父组件通过 props 向子组件传递数据,子组件仅通过 props 接收数据。使用全局变量共享数据会破坏组件的独立性和纯粹性,导致逻辑混乱、难以维护。而基于 props 的通信能保证数据流向清晰,组件行为可预测,这也是 React 推荐的最佳实践。

如果需要在更深层级的组件间共享数据(避免 props 逐层传递),可以了解 React 的 Context API 或状态管理库(如 Redux),它们是更规范的跨组件数据共享方案。

相关推荐
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60617 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
执笔论英雄8 小时前
【大模型学习cuda】入们第一个例子-向量和
学习
wdfk_prog8 小时前
[Linux]学习笔记系列 -- [drivers][input]input
linux·笔记·学习
崔庆才丨静觅8 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
ouliten8 小时前
cuda编程笔记(36)-- 应用Tensor Core加速矩阵乘法
笔记·cuda
崔庆才丨静觅8 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment8 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端