React 18
中组件通信的方式有很多,选择哪种方式取决于具体的需求和应用的复杂度。常见的方式包括:
- 父子组件通信:通过 props 传递数据和回调函数。
- 兄弟组件通信:通过共同的父组件共享状态。
- 使用 Context API:适用于跨越多个层级的组件通信。
- 使用 Redux:适用于大型应用中的复杂状态管理。
- 使用事件总线:通过发布/订阅模式在组件之间传递消息。
1. 父子组件通信
通过 Props 传递数据和回调函数
父组件可以通过 props 向子组件传递数据和回调函数,子组件通过调用回调函数将数据传回父组件。
父组件:
import React, { useState } from 'react';
import ChildComponent from './ChildComponent';
const ParentComponent = () => {
const [message, setMessage] = useState('父:儿子你好');
const handleChildMessage = (childMessage) => {
console.log('Message from Child:', childMessage);
};
return (
<div>
<h1>{message}</h1>
<ChildComponent message={message} onMessageChange={handleChildMessage} />
</div>
);
};
export default ParentComponent;
子组件:
import React from 'react';
const ChildComponent = ({ message, onMessageChange }) => {
const sendMessageToParent = () => {
onMessageChange('Hello from Child');
};
return (
<div>
<h2>{message}</h2>
<button onClick={sendMessageToParent}>Send Message to Parent</button>
</div>
);
};
export default ChildComponent;
2. 兄弟组件通信
通过共同的父组件
兄弟组件可以通过共同的父组件来共享状态和回调函数。
父组件:
import React, { useState } from 'react';
import Child111 from './Child111';
import Child222 from './Child222';
const ParentComponent = () => {
const [sharedMessage, setSharedMessage] = useState('');
const handleMessageChange = (message) => {
setSharedMessage(message);
};
return (
<div>
<Child111 onMessageChange={handleMessageChange} />
<Child222 message={sharedMessage} />
</div>
);
};
export default ParentComponent;
兄弟组件:
// Child111.js 孩子1
import React from 'react';
const Child111 = ({ onMessageChange }) => {
const sendMessage = () => {
onMessageChange('Message from Child111');
};
return (
<div>
<button onClick={sendMessage}>Send Message</button>
</div>
);
};
export default Child111;
// Child222.js 孩子2
import React from 'react';
const Child222 = ({ message }) => {
return (
<div>
<h2>{message}</h2>
</div>
);
};
export default Child222;
3. 使用 Context API
Context API 适用于需要在组件树中多个层级传递数据的情况。(爷爷和孙子通信)
创建 Context:
import React, { createContext, useState } from 'react';
export const MessageContext = createContext();
const MessageProvider = ({ children }) => {
const [message, setMessage] = useState('Hello from Context');
return (
<MessageContext.Provider value={{ message, setMessage }}>
{children}
</MessageContext.Provider>
);
};
export default MessageProvider;
使用 Context:
// ParentComponent.js 父组件--------------------
import React from 'react';
import MessageProvider from './MessageProvider';
import ChildComponent from './ChildComponent';
const ParentComponent = () => {
return (
<MessageProvider>
<ChildComponent />
</MessageProvider>
);
};
export default ParentComponent;
// ChildComponent.js 子组件-----------------------
import React, { useContext } from 'react';
import { MessageContext } from './MessageProvider';
const ChildComponent = () => {
const { message, setMessage } = useContext(MessageContext);
const changeMessage = () => {
setMessage('Updated Message from Child');
};
return (
<div>
<h2>{message}</h2>
<button onClick={changeMessage}>Change Message</button>
</div>
);
};
export default ChildComponent;
4. 使用 Redux
Redux 是一个流行的状态管理库,适用于大型应用程序中的复杂状态管理。
安装 Redux:
npm install redux react-redux
创建 Redux Store:
// store.js
import { createStore } from 'redux';
const initialState = {
message: 'Hello from Redux'
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'SET_MESSAGE':
return {
...state,
message: action.payload
};
default:
return state;
}
};
const store = createStore(reducer);
export default store;
使用 Redux:
// ParentComponent.js
import React from 'react';
import { Provider } from 'react-redux';
import store from './store';
import ChildComponent from './ChildComponent';
const ParentComponent = () => {
return (
<Provider store={store}>
<ChildComponent />
</Provider>
);
};
export default ParentComponent;
// ChildComponent.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
const ChildComponent = () => {
const message = useSelector((state) => state.message);
const dispatch = useDispatch();
const changeMessage = () => {
dispatch({ type: 'SET_MESSAGE', payload: 'Updated Message from Child' });
};
return (
<div>
<h2>{message}</h2>
<button onClick={changeMessage}>Change Message</button>
</div>
);
};
export default ChildComponent;
5. 使用事件总线(Event Bus)
事件总线是一种通过发布/订阅模式在组件之间传递消息的方式。可以使用第三方库如 mitt
或者自己实现一个简单的事件总线。
安装 mitt:
npm install mitt
创建事件总线:
// eventBus.js
import mitt from 'mitt';
const emitter = mitt();
export default emitter;
使用事件总线:
// ParentComponent.js
import React from 'react';
import emitter from './eventBus';
import ChildComponent from './ChildComponent';
const ParentComponent = () => {
const handleMessage = (message) => {
console.log('Received message:', message);
};
React.useEffect(() => {
emitter.on('message', handleMessage);
return () => {
emitter.off('message', handleMessage);
};
}, []);
return (
<div>
<ChildComponent />
</div>
);
};
export default ParentComponent;
// ChildComponent.js
import React from 'react';
import emitter from './eventBus';
const ChildComponent = () => {
const sendMessage = () => {
emitter.emit('message', 'Hello from Child');
};
return (
<div>
<button onClick={sendMessage}>Send Message</button>
</div>
);
};
export default ChildComponent;
总结
每种方式都有其适用的场景和优缺点,开发者可以根据具体需求选择合适的方式来实现组件之间的通信。