前言
在上一篇文章《React父子组件通信方式详解》中我们了解了React父子组件通信的4中方式。
本文中我们将详细了解react兄弟组件通信方式。
React技能树
React 技能树
├── JSX
│ ├── 语法
│ ├── 元素渲染
│ ├── 组件
│ ├── Props
│ ├── State
│ └── 生命周期
├── 组件通信
│ ├── 父子组件通信
│ ├── 兄弟组件通信
│ ├── 跨级组件通信
│ ├── Context
│ └── Redux
├── 样式
│ ├── 内联样式
│ ├── CSS Modules
│ └── Styled Components
├── 路由
│ ├── React Router
│ ├── 动态路由
│ └── 嵌套路由
├── 数据请求
│ ├── Axios
│ ├── Fetch
│ └── GraphQL
├── 状态管理
│ ├── Redux
│ ├── MobX
│ └── Recoil
├── 常用库和框架
│ ├── Ant Design
│ ├── Material UI
│ ├── Bootstrap
│ ├── Semantic UI
│ └── Tailwind CSS
├── 测试
│ ├── Jest
│ ├── Enzyme
│ └── React Testing Library
├── 构建工具
│ ├── Webpack
│ └── Parcel
└── 服务端渲染
├── Next.js
└── Gatsby
在React中,组件之间的通信可以通过父组件向子组件传递props,也可以通过子组件向父组件传递事件回调函数来实现。但是,如果兄弟组件之间需要进行通信,React并没有提供内置的方式来实现这一点。但是,我们可以通过一些技巧来实现兄弟组件之间的通信,如下所示:
通过共同的父组件传递props
// Parent Component
import React, {
useState } from 'react';
import BrotherA from './BrotherA';
import BrotherB from './BrotherB';
function Parent() {
const [message, setMessage] = useState('');
const handleSend = (message) => {
setMessage(message);
}
return (
<div>
<BrotherA onSend={
handleSend} />
<BrotherB message={
message} />
</div>
);
}
// BrotherA Component
import React, {
useState } from 'react';
function BrotherA(props) {
const [message, setMessage] = useState('');
const handleClick = () => {
props.onSend(message);
}
return (
<div>
<input type="text" value={
message} onChange={
(e) => setMessage(e.target.value)} />
<button onClick={
handleClick}>Send</button>
</div>
);
}
// BrotherB Component
import React from 'react';
function BrotherB(props) {
return (
<div>
<p>{
props.message}</p>
</div>
);
}
在上面的示例中,Parent组件作为BrotherA和BrotherB组件的父组件,它负责传递BrotherB需要的消息,同时它也传递了一个onSend回调函数给BrotherA,以便BrotherA可以调用该函数并传递消息。
使用React Context
另一种实现兄弟组件之间通信的方式是使用React Context,它可以让我们在组件之间共享数据。
在下面这个示例中,我们将使用React Context API来创建一个全局状态管理器,BrotherA和BrotherB组件都可以访问和更新该状态。我们需要在应用程序中定义一个名为MessageContext的React context,并提供一个名为setMessage的操作函数来更新message状态。
// MessageContext.js
import {
createContext } from 'react';
const MessageContext = createContext({
message: '',
setMessage: () => {
},
});
export default MessageContext;
在App组件中,我们需要使用MessageContext.Provider组件包装BrotherA和BrotherB组件,以便它们可以访问MessageContext。
// App.js
import BrotherA from './BrotherA';
import BrotherB from './BrotherB';
import MessageContext from './MessageContext';
function App() {
const [message, setMessage] = useState('');
return (
<div>
<MessageContext.Provider value={
{
message, setMessage }}>
<BrotherA />
<BrotherB />
</MessageContext.Provider>
</div>
);
}
export default App;
在BrotherA组件中,我们可以使用useContext hook来从MessageContext中获取setMessage操作函数,并调用它来更新message状态。
// BrotherA.js
import {
useContext } from 'react';
import MessageContext from './MessageContext';
function BrotherA() {
const {
setMessage } = useContext(MessageContext);
function handleClick() {
setMessage('Hello from BrotherA!');
}
return (
<div>
<button onClick={
handleClick}>Send message to BrotherB</button>
</div>
);
}
export default BrotherA;
在BrotherB组件中,我们也可以使用useContext hook来从MessageContext中获取message状态。
// BrotherB.js
import {
useContext } from 'react';
import MessageContext from './MessageContext';
function BrotherB() {
const {
message } = useContext(MessageContext);
return (
<div>
<p>Message from BrotherA: {
message}</p>
</div>
);
}
export default BrotherB;
这两种方法都可以实现兄弟组件之间的通信,具体选择哪种方法取决于你的具体需求。在一些情况下,使用Context可能更方便,因为它可以减少需要传递的props的数量。但是,在其他情况下,使用父组件传递props可能更加直接和可读性更好。
除了在父组件中传递props和使用React Context之外,还有一些其他的方式可以实现兄弟组件之间的通信。以下是其中一些常见的方法:
使用Redux
使用Redux可以方便地共享状态和管理应用程序的状态,因此它也可以用于兄弟组件之间的通信。通过将状态存储在Redux store中,兄弟组件可以在需要时访问并更新该状态。这种方法需要在应用程序中引入Redux,需要在Redux store中定义状态和操作状态的函数。
在这个示例中,我们将使用Redux来管理message状态,BrotherA和BrotherB组件都可以访问和更新该状态。我们需要在应用程序中安装Redux,并定义一个包含message状态的Redux store,以及更新该状态的操作函数。
// store.js
import {
createStore } from 'redux';
const initialState = {
message: '' };
function messageReducer(state = initialState, action) {
switch (action.type) {
case 'SET_MESSAGE':
return {
...state, message: action.payload };
default:
return state;
}
}
export const store = createStore(messageReducer);
在BrotherA组件中,我们可以使用useSelector hook来从Redux store中获取message状态,以及使用useDispatch hook来调用setMessage操作函数。
// BrotherA.js
import {
useSelector, useDispatch } from 'react-redux';
function BrotherA() {
const message = useSelector(state => state.message);
const dispatch = useDispatch();
function handleClick() {
dispatch({
type: 'SET_MESSAGE', payload: 'Hello from BrotherA!' });
}
return (
<div>
<p>Message from BrotherB: {
message}</p>
<button onClick={
handleClick}>Send message to BrotherB</button>
</div>
);
}
export default BrotherA;
在BrotherB组件中,我们也可以使用useSelector hook来从Redux store中获取message状态,以及使用useDispatch hook来调用setMessage操作函数。
// BrotherB.js
import {
useSelector, useDispatch } from 'react-redux';
function BrotherB() {
const message = useSelector(state => state.message);
const dispatch = useDispatch();
function handleClick() {
dispatch({
type: 'SET_MESSAGE', payload: 'Hello from BrotherB!' });
}
return (
<div>
<p>Message from BrotherA: {
message}</p>
<button onClick={
handleClick}>Send message to BrotherA</button>
</div>
);
}
export default BrotherB;
使用EventBus
EventBus是一个事件总线,可以让组件之间通过发布和订阅事件来通信。通过使用EventBus,兄弟组件可以在需要时发布事件,并通过订阅事件来接收其他组件发送的事件。这种方法需要在应用程序中引入EventBus库,并使用事件名称来标识特定事件。
在这个示例中,我们将使用EventBus库来实现BrotherA和BrotherB组件之间的通信。我们需要在应用程序中安装EventBus库,并定义一个事件总线。在BrotherA组件中,我们可以使用EventBus来发布名为'message'的事件,并在BrotherB组件中订阅该事件。
// EventBus.js
import {
EventEmitter } from 'events';
const eventBus = new EventEmitter();
export default eventBus;
在BrotherA组件中,我们可以使用EventBus来发布名为'message'的事件。
javascript
Copy code
// BrotherA.js
import eventBus from './EventBus';
function BrotherA() {
function handleClick() {
eventBus.emit('message', 'Hello from BrotherA!');
}
return (
<div>
<button onClick={
handleClick}>Send message to BrotherB</button>
</div>
);
}
export default BrotherA;
在BrotherB组件中,我们可以使用EventBus来订阅名为'message'的事件,并在事件被触发时更新message状态。
// BrotherB.js
import {
useState, useEffect } from 'react';
import eventBus from './EventBus';
function BrotherB() {
const [message, setMessage] = useState('');
useEffect(() => {
const handleEvent = (data) => {
setMessage(data);
};
eventBus.on('message', handleEvent);
return () => {
eventBus.off('message', handleEvent);
};
}, []);
return (
<div>
<p>Message from BrotherA: {
message}</p>
</div>
);
}
export default BrotherB;
以上这些方法都可以实现兄弟组件之间的通信,但它们的实现和使用方法各有不同,具体取决于你的具体需求和应用程序的复杂性。
✍创作不易,求关注😄,点赞👍,收藏⭐️