react+ts中函数组件父子通信方式

1. 父组件通过 Props 向子组件传递数据

这是最常见也是最基本的父子组件通信方式。父组件通过 props 将数据或回调函数传递给子组件。

示例代码:
// 子组件接收来自父组件的数据
interface ChildProps {
  message: string;
}

const ChildComponent: React.FC<ChildProps> = ({ message }) => {
  return <h1>{message}</h1>;
};

// 父组件向子组件传递数据
const ParentComponent = () => {
  const parentMessage = "Hello from Parent!";
  
  return (
    <ChildComponent message={parentMessage} />
  );
};

2. 子组件通过回调函数通知父组件

如果子组件需要与父组件交互,则可以通过父组件传递一个回调函数作为 prop,在子组件中调用该函数以通知父组件某些事件的发生。

示例代码:
interface ChildProps {
  onButtonClick: () => void;
}

const ChildComponent: React.FC<ChildProps> = ({ onButtonClick }) => {
  return (
    <button onClick={onButtonClick}>
      Click Me to Notify Parent
    </button>
  );
};


// 父组件提供回调函数处理逻辑
const ParentComponent = () => {
  const notifyParent = () => {
    console.log("Button clicked in child component!");
  };

  return (
    <ChildComponent onButtonClick={notifyParent} />
  );
};
3. 使用 Refs 访问子组件实例

虽然不建议频繁使用 refs 来管理子组件的状态或行为,但在特殊场景下仍然可行。可以结合 React.forwardRefuseImperativeHandle 来暴露子组件的功能供父组件调用。

示例代码:
// 子组件定义并通过 forwardRef 曝露功能
interface ChildProps{}

const ChildComponent = React.forwardRef((props:ChildProps, ref) => {
  const [count, setCount] = React.useState(0);
  // 暴露方法给父组件
  React.useImperativeHandle(ref, () => ({
    increment() {
      setCount(count + 1);
    },
  }));

  return <div>Current Count: {count}</div>;
});

export default ChildComponent;


// 父组件利用 useRef 获取子组件实例
const ParentComponent = () => {
  const childRef = React.useRef<any>();
  const handleClickIncrement = () => {
    childRef.current?.increment();
  };

  return (
    <>
      <button onClick={handleClickIncrement}>Increment Child State</button>
      <ChildComponent ref={childRef} />
    </>
  );
};
4. 使用 Context 提供全局状态共享

对于复杂的应用程序结构,可能涉及多个层级间的通信需求。此时可以采用上下文 API (React.createContext) 来简化跨层通信过程。

示例代码:
// 创建 context 并设置默认值
const MyContext = React.createContext<string | null>(null);

// Provider 组件封装状态
const ContextProvider = ({ children }: { children: React.ReactNode }) => {
  const [value, setValue] = React.useState("Initial Value");

  return (
    <MyContext.Provider value={value}>
      {children}
    </MyContext.Provider>
  );
};


// 子组件消费 context 数据
const ChildComponent = () => {
  const contextValue = React.useContext(MyContext);

  return <p>Received From Context: {contextValue}</p>;
};


// 父组件嵌套 provider 及消费者
const ParentComponent = () => {
  return (
    <ContextProvider>
      <ChildComponent />
    </ContextProvider>
  );
};

### 子组件获取父组件元素的方法 #### React 中的操作方法 在 React 中,子组件通常不应该直接操作父组件的 DOM 元素。然而,在某些情况下确实需要这样做时,可以采用 `ref` 结合回调函数方式实现跨层级通信[^2]。 ```jsx // 父组件 ParentComponent.jsx import React, { useRef } from 'react'; function ParentComponent() { const parentRef = useRef(null); return ( <> <div ref={parentRef}>这是父级组件的内容</div> <ChildComponent getParentElement={() => parentRef.current} /> </> ); } // 子组件 ChildComponent.jsx function ChildComponent({ getParentElement }) { function handleClick() { console.log(getParentElement()); } return <button onClick={handleClick}>点击获取父级元素</button>; } ``` 这种方式通过传递回调函数给子组件,使后者能够在必要时刻调用该函数从而间接获得对父组件特定部分的引用。 #### Vue 中的操作方式 对于 Vue 来说,虽然也提倡避免直接操纵DOM,但在实际应用中有几种途径可以让子组件访问到父组件的数据或属性: 1. **事件总线**:创建一个独立于任何组件之外的对象作为消息中心; 2. **$refs**:利用 `$refs` 属性可以直接引用已注册过的子组件实例对象;不过这里讨论的是相反的情况——即由子向上传递信息至父级,则应考虑使用自定义事件机制(`emit`)通知上级组件处理逻辑[^3]。 实际上更推荐的做法是在父子之间建立双向绑定或者借助 Vuex 这样的全局状态管理工具来进行数据共享而不是直接接触对方的真实 DOM 节点。 #### Angular 中的操作手段 Angular 提供了一种更为结构化的方式来让子组件与父组件交互,主要依赖输入输出装饰器 (`@Input()` 和 `@Output()`) 实现单向数据流以及 EventEmitter 发布订阅模式完成反向反馈[^1]。 如果非要触及父类模板内的某个具体标签的话,可以通过 ViewChild 或 ContentChild 注入器配合 ElementRef 接口达成目的,但这不是官方所鼓励的最佳实践方向。 ```typescript // child.component.ts import { Component, Input, Output, EventEmitter, AfterViewInit, ElementRef, ViewChild } from '@angular/core'; @Component({ selector: 'app-child', template: `<p>这里是子组件。</p>` }) export class ChildComponent implements AfterViewInit { @ViewChild('target', { static: false }) private target!: ElementRef; ngAfterViewInit(): void { // 可在此处安全地访问 this.target.nativeElement 获取目标元素 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值