父子组件通信
- 父传子
- 实现思路:通过在父组件中向子组件传递属性(props)来实现通信。子组件通过接收这些props来获取父组件的数据。
- 示例:
import React from 'react';
// 子组件
const ChildComponent = ({ data }) => {
return <div>{data}</div>;
};
// 父组件
const ParentComponent = () => {
const parentData = '来自父组件的数据';
return <ChildComponent data={parentData} />;
};
export default ParentComponent;
- 子传父
- 实现思路:父组件将一个函数作为props传递给子组件,子组件调用该函数并将数据作为参数传递,从而实现将数据传递给父组件。
- 示例:
import React, { useState } from'react';
// 子组件
const ChildComponent = ({ handleChildData }) => {
const childData = '来自子组件的数据';
return <button onClick={() => handleChildData(childData)}>传递数据给父组件</button>;
};
// 父组件
const ParentComponent = () => {
const [receivedData, setReceivedData] = useState('');
const handleChildData = (data) => {
setReceivedData(data);
};
return (
<div>
<ChildComponent handleChildData={handleChildData} />
<p>接收到的数据: {receivedData}</p>
</div>
);
};
export default ParentComponent;
非父子组件通信
- 使用Context(上下文)
- 实现思路:创建一个Context对象,通过Provider将数据传递给后代组件,无论组件嵌套多深,后代组件都可以通过Consumer或者useContext Hook来获取数据。
- 示例:
import React, { createContext, useState } from'react';
// 创建Context
const MyContext = createContext();
// 中间组件
const MiddleComponent = () => {
return (
<MyContext.Consumer>
{value => <div>非父子组件获取到的数据: {value}</div>}
</MyContext.Consumer>
);
};
// 顶层父组件
const TopParentComponent = () => {
const [sharedData, setSharedData] = useState('共享数据');
return (
<MyContext.Provider value={sharedData}>
<MiddleComponent />
</MyContext.Provider>
);
};
export default TopParentComponent;
- 使用状态管理库(如Redux)
- 实现思路:将应用的状态存储在一个单一的store中,各个组件通过dispatch action来更新store中的状态,同时可以订阅store的变化来更新自身。
- 示例(简单示意,实际使用需更多配置):
// 安装redux及react - redux
// 定义action
const SET_DATA ='SET_DATA';
const setData = (data) => ({ type: SET_DATA, payload: data });
// 定义reducer
const initialState = { sharedData: '' };
const dataReducer = (state = initialState, action) => {
switch (action.type) {
case SET_DATA:
return { ...state, sharedData: action.payload };
default:
return state;
}
};
// 创建store
import { createStore } from'redux';
const store = createStore(dataReducer);
// 组件使用
import React from'react';
import { useSelector, useDispatch } from'react - redux';
const ComponentA = () => {
const dispatch = useDispatch();
return <button onClick={() => dispatch(setData('组件A设置的数据'))}>设置数据</button>;
};
const ComponentB = () => {
const sharedData = useSelector(state => state.sharedData);
return <div>组件B获取到的数据: {sharedData}</div>;
};
- 使用事件总线(自定义)
- 实现思路:创建一个事件中心,各个组件在需要通信时向事件中心发布事件或者订阅事件。
- 示例:
// 创建事件总线
class EventBus {
constructor() {
this.events = {};
}
on(eventName, callback) {
if (!this.events[eventName]) {
this.events[eventName] = [];
}
this.events[eventName].push(callback);
}
emit(eventName, data) {
if (this.events[eventName]) {
this.events[eventName].forEach(callback => callback(data));
}
}
}
const eventBus = new EventBus();
// 组件A发布事件
const ComponentA = () => {
const publishData = () => {
eventBus.emit('custom - event', '来自组件A的数据');
};
return <button onClick={publishData}>发布事件</button>;
};
// 组件B订阅事件
const ComponentB = () => {
React.useEffect(() => {
const handleEvent = (data) => {
console.log('组件B接收到的数据:', data);
};
eventBus.on('custom - event', handleEvent);
return () => {
eventBus.off('custom - event', handleEvent);
};
}, []);
return <div>组件B等待接收数据</div>;
};