写在前面
React组件之间的通信一般分为下面几种情况:
- 父子组件之间的通信
- 非嵌套组件之间的通信
父子组件之间的通信
这是最简单也是最常用的一种通信方式:父组件通过向子组件传递 props,子组件得到 props 后进行相应的处理。下面贴两段代码:
父组件 FatherComp.js:
import React from "react";
import Son from "./SonComp";
export default function FatherComp() {
return (
<div>
<Son title="我就是高阶领主" />
</div>
);
}
复制代码
子组件 SonComp.js:
import React from "react";
const Son = (props) => {
return <h1>{props.title}</h1>;
};
export default Son;
复制代码
这个也没啥好说的,最简单的透传,下面主要介绍非嵌套的组件之间的通信。
非嵌套组件之间的通信
简单来说就是组件之间没有什么关联,需要通信就需要有个媒介,这里我们采用自定义事件的方式来进行通信:
首先需要安装一个event包
npm install events --save
复制代码
新建一个 event.js,引入 events 包,并向外提供一个事件对象,供通信时使用:
import { EventEmitter } from "events";
export default new EventEmitter();
复制代码
App.js
import React from "react";
import "./styles.css";
import Comp1 from "./Comp1";
import Comp2 from "./Comp2";
import FatherComp from "./FatherComp";
export default function App() {
return (
<div>
<FatherComp />
<Comp1 />
<Comp2 />
</div>
);
}
复制代码
Comp1.js
import React, { useState, useEffect } from "react";
import emitter from "./event";
export default function Comp1() {
const [msg, setMsg] = useState(null);
useEffect(() => {
// 声明一个自定义事件
// 在组件装载完成以后
this.eventEmitter = emitter.addListener("clickMe", (msg) => {
setMsg(msg);
});
// 组件销毁前移除事件监听
return () => {
emitter.removeListener(this.eventEmitter);
};
}, []);
return (
<div>
{msg}
组件1
</div>
);
}
复制代码
Comp2.js
import React from "react";
import emitter from "./event";
export default function Comp2() {
const cb = () => {
return () => {
// 触发自定义事件
emitter.emit("clickMe", "Hello");
};
};
return (
<div>
组件2<button onClick={cb()}>点击我</button>
</div>
);
}
复制代码
下面我们写一个简单的事件demo来深入了解一下:
var eventPool = {
map: {},
// 事件订阅
on: (name, cb) => {
eventPool.map[name] = cb;
},
// 事件发射
emit: (name, ...args) => {
const cb = eventPool.map[name];
cb && cb(...args);
}
};
// xxx为事件名,有两个参数
eventPool.on("xxx", (p1, p2) => console.log(p1, p2));
// 发射完直接打印了这两个参数
eventPool.emit("xxx", 1, 2);
复制代码
总结
自定义事件在组件之间没有直接联系的情况下使用还是很方便的,总之就是香~
这里是本篇文章涉及的代码,项目地址在
www.zhangzheyi1.com/2021/07/30/…
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END