React 之 组件通信方式

1、Props

1.1 父传子

步骤:

父组件通过绑定prop向子组件传递

代码示例:

interface Props {
  message: string;
}

// 子组件
const Child = (props: Props) => {
  const { message } = props;

  return (
    <div>
      <h1>这是子组件</h1>
      <p>从父组件接收的数据:{message}</p>
    </div>
  );
};

// 父组件
const ParentToChild = () => {
  const msg = "传递给子组件";

  return (
    <div>
      <h1>这是父组件</h1>
      <div style={{ background: "#D8D8D8" }}>
        <Child message={msg} />
      </div>
    </div>
  );
};

export default ParentToChild;

1.2 子传父

步骤:

1. 父组件向子组件绑定回调函数
2. 子组件触发回调函数,将参数返回父组件

代码示例:

import { useState } from "react";

interface Props {
  changeMessageEvent: Function;
}

// 子组件
const Child = (props: Props) => {
  const { changeMessageEvent } = props;

  // 触发回调函数,将参数返回父组件
  const clickEvent = () => {
    changeMessageEvent("这是修改后的 message");
  };

  return (
    <div>
      <h1>这是子组件</h1>
      <button onClick={clickEvent}>点我修改父组件的message</button>
    </div>
  );
};

// 父组件
const ParentToChild = () => {
  const [message, setMessage] = useState("原 message");

  const changeMessage = (msg: string) => {
    setMessage(msg);
  };

  return (
    <div>
      <h1>这是父组件</h1>
      <p>message: {message}</p>

      <div style={{ background: "#D8D8D8", padding: "10px" }}>
        {/* 向子组件绑定回调函数 */}
        <Child changeMessageEvent={changeMessage} />
      </div>
    </div>
  );
};

export default ParentToChild;

1.3 兄弟组件通信

说明:通过父组件来实现兄弟之间的通信
步骤:

1. 父组件分别向子组件绑定属性和回调函数
2. 子组件触发回调函数,将参数返回父组件
3. 父组件接收参数后,将参数传递到另一个子组件

代码示例:

import { useState } from "react";

// 子组件1
interface Child1Props {
  mssage1: string;
  child1Event: Function;
}
const Child1 = (prop: Child1Props) => {
  const { child1Event, mssage1 } = prop;

  // 【步骤2】:子组件触发回调函数,将参数返回父组件
  const clickEvent = () => {
    child1Event("我来自子组件1---" + new Date().getTime());
  };

  return (
    <div style={{ background: "rgb(148,180,214)", padding: "10px" }}>
      <h1>这是子组件1</h1>
      <p>接收的message:{mssage1}</p>
      <button onClick={clickEvent}>点击向子组件2传递参数</button>
    </div>
  );
};

// 子组件2
interface Child2Props {
  mssage2: string;
  child2Event: Function;
}
const Child2 = (prop: Child2Props) => {
  const { child2Event, mssage2 } = prop;

  // 【步骤2】:子组件触发回调函数,将参数返回父组件
  const clickEvent = () => {
    child2Event("我来自子组件2--" + new Date().getTime());
  };

  return (
    <div style={{ background: "rgb(232,217,186)", padding: "10px" }}>
      <h1>这是子组件2</h1>
      <p>接收的message:{mssage2}</p>
      <button onClick={clickEvent}>点击向子组件1传递参数</button>
    </div>
  );
};

// 父组件
const ChildToChild = () => {
  const [mssage1, setMessage1] = useState("组件1message");
  const [mssage2, setMessage2] = useState("组件2message");

  // 子组件1的事件处理逻辑
  const child1Event = (newMessage: string) => {
    console.log("子组件1的事件被触发:", newMessage);
    // 【步骤3】:修改子组件2的message
    setMessage2(newMessage);
  };

  // 子组件2的事件处理逻辑
  const child2Event = (newMessage: string) => {
    // 【步骤3】:修改子组件1的message
    setMessage1(newMessage);
  };

  return (
    <div>
      <h1>这是父组件</h1>
      {/* 【步骤1】:父组件分别向子组件绑定属性和回调函数 */}
      <Child1 child1Event={child1Event} mssage1={mssage1} />
      <Child2 child2Event={child2Event} mssage2={mssage2} />
    </div>
  );
};

export default ChildToChild;

1.4 祖孙通信

可以通过props一层一层传递接收
这个这里参考 1.1 和 1.2
不建议使用这种方法

2、Context

2.1 跨层组件通信

步骤:

1. 通过 createContext 创建一个对象 ctx
2. 顶层组件通过 ctx.Provider 提供数据
3. 底层组件通过 useContext 获取数据

代码实现:

import { createContext, useContext } from "react";

// 【步骤1】. createContext 创建一个对象 ctx
const MessageContext = createContext<string>("");

// 孙组件
const Son = () => {
  // 【步骤3】. 底层组件通过 useContext 获取参数
  const msg = useContext(MessageContext);
  
  return (
    <div style={{ background: "rgb(148,180,214)", padding: "10px" }}>
      <h1>孙组件</h1>
      <p>接收到的信息:{msg}</p>
    </div>
  );
};

// 父组件
const Parent = () => {
  return (
    <div style={{ background: "rgb(232,217,186)", padding: "10px" }}>
      <h1>父组件</h1>
      <Son />
    </div>
  );
};

// 爷组件
const Grand = () => {
  const msg = "爷组件传递的信息";
  return (
    <div style={{ background: "rgb(169,212,171)", padding: "10px" }}>
      <h1>爷组件</h1>
      {/* 【步骤2】. 顶层组件通过 ctx.Provider 提供数据 */}
      <MessageContext.Provider value={msg}>
        <Parent />
      </MessageContext.Provider>
    </div>
  );
};

const GrandToSon = () => {
  return (
    <div>
      <h1>祖孙组件通信</h1>
      <Grand />
    </div>
  );
};

export default GrandToSon;

3、rudux

说明:我这里使用 react-redux + redux-toolkit
我这里有文章介绍:文章链接
代码示例:(这里以修改message为例)

import { useDispatch, useSelector } from "react-redux";
import { updateMessage } from "@/redux/modules/cmponents-comm";

// 组件1
const Comp1 = () => {
  const message = useSelector((state: any) => state.componentComm);
  const dispatch = useDispatch();

  return (
    <div style={{ background: "rgb(148,180,214)", padding: "10px" }}>
      <h1>组件1</h1>
      <p>接收的message:{message}</p>
      <button onClick={() => dispatch(updateMessage("组件1设置message"))}>
        点击修改message
      </button>
    </div>
  );
};

// 组件2
const Comp2 = () => {
  const message = useSelector((state: any) => state.componentComm);
  const dispatch = useDispatch();

  return (
    <div style={{ background: "rgb(232,217,186)", padding: "10px" }}>
      <h1>组件2</h1>
      <p>接收的message:{message}</p>
      <button onClick={() => dispatch(updateMessage("组件2设置message"))}>
        点击修改message
      </button>
    </div>
  );
};

const ReduxComponentsComm = () => {
  return (
    <div>
      <h1>Redux 组件通信</h1>
      <Comp1 />
      <Comp2 />
    </div>
  );
};

export default ReduxComponentsComm;

src/redux/modules/cmponents-comm

import { createSlice } from "@reduxjs/toolkit";

// 创建组件通信的 slice

export const commSlice = createSlice({
  name: "components-comm",
  initialState: "redux 组件通信",
  reducers: {
    updateMessage: (state, action) => {
      state = action.payload;
      return state;
    },
  },
});

export const { updateMessage } = commSlice.actions;

export default commSlice.reducer;

4、使用事件

使用发布-订阅模式
我这里使用 events,安装:

npm install events

代码示例:

import { useEffect, useState } from "react";

// 引入 events
const EventEmitter = require("events");

const ee = new EventEmitter();

// 组件1
const Comp1 = () => {
  const [message, setMessage] = useState<string>("");
  
  useEffect(() => {
    // 1、订阅事件
    ee.on("message", function (text: string) {
      setMessage(text);
    });
  }, []);

  return (
    <div>
      <h1>组件1</h1>
      <p>接收组件参数:{message}</p>
    </div>
  );
};

// 组件2
const Comp2 = () => {
  const clickEvent = () => {
    // 2、发布事件
    ee.emit("message", "传递数据--" + new Date().getTime());
  };

  return (
    <div>
      <h1>组件2</h1>
      <button onClick={clickEvent}>向组件1传参</button>
    </div>
  );
};

const EventsComm = () => {
  return (
    <div>
      <Comp1 />
      <Comp2 />
    </div>
  );
};

export default EventsComm;
  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值