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;