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

React中如何向孙组件传递Props?当前实现出现undefined问题

解决React中无需Prop Drilling传递name属性给深层组件的问题

问题分析

你当前的实现有两个核心问题导致MyComponent无法拿到name值:

  1. ParentComponent的子元素处理逻辑错误:遍历外层ChildComponent后,直接返回了内层MyComponent的克隆结果,相当于丢弃了原有的ChildComponent层级,导致组件结构混乱,属性传递路径断裂。
  2. 示例代码结构语法错误:第二个ChildComponent的闭合标签写法错误,应该是<ChildComponent><MyComponent /></ChildComponent>,而非拆分的闭合标签。

方案一:修正cloneElement逻辑(保留组件层级)

调整ParentComponent的实现,正确克隆ChildComponent并替换它的子元素,确保层级结构完整的同时传递属性:

import { ReactElement, Children, cloneElement, isValidElement } from 'react';

const ParentComponent = ({ children }: { children: React.ReactNode }) => {
  return Children.map(children, (child, childIndex) => {
    // 跳过非React元素类型的子节点
    if (!isValidElement(child)) return child;

    // 遍历ChildComponent的子元素,为MyComponent添加name属性
    const updatedInnerChildren = Children.map(child.props.children, (innerChild, innerIndex) => {
      if (!isValidElement(innerChild)) return innerChild;
      return cloneElement(innerChild as ReactElement, {
        name: `${childIndex}-${innerIndex}-name`,
      });
    });

    // 克隆原ChildComponent,替换它的子元素为更新后的内容
    return cloneElement(child as ReactElement, {
      children: updatedInnerChildren,
    });
  });
};

修正后的组件结构:

<ParentComponent name="name">
    <ChildComponent>
        <MyComponent />
    </ChildComponent>
    <ChildComponent>
        <MyComponent />
    </ChildComponent>
</ParentComponent>

方案二:使用React Context(推荐,彻底避免Prop Drilling)

如果你的组件层级更深或需要跨多个层级传递数据,React Context是更优雅的解决方案:

1. 创建Context

// NameContext.tsx
import { createContext, useContext } from 'react';

type NameContextType = string | undefined;
const NameContext = createContext<NameContextType>(undefined);

export const NameProvider = NameContext.Provider;
export const useName = () => useContext(NameContext);

2. 在ParentComponent中提供Context值

import { NameProvider, isValidElement, Children, cloneElement } from 'react';
import { NameProvider } from './NameContext';

const ParentComponent = ({ name, children }: { name: string; children: React.ReactNode }) => {
  return Children.map(children, (child, childIndex) => {
    if (!isValidElement(child)) return child;

    const updatedInnerChildren = Children.map(child.props.children, (innerChild, innerIndex) => {
      if (!isValidElement(innerChild)) return innerChild;
      // 为每个MyComponent生成唯一name并提供Context
      const uniqueName = `${childIndex}-${innerIndex}-${name}`;
      return (
        <NameProvider value={uniqueName}>
          {innerChild}
        </NameProvider>
      );
    });

    return cloneElement(child as ReactElement, {
      children: updatedInnerChildren,
    });
  });
};

3. 在MyComponent中消费Context

import { useName } from './NameContext';

const MyComponent = () => {
  const name = useName();
  console.log(name); // 现在可以正确获取到name值

  return (
    <div id={`${name}-component`}>...</div>
  );
};

内容的提问来源于stack exchange,提问作者Pollák Bence

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:30:16