react组件如何通讯
React 组件通讯方式
React 组件间的通讯方式主要包括以下几种方法,适用于不同场景下的数据传递和状态管理需求。
父子组件通讯(Props 传递)
父组件通过 props 向子组件传递数据或回调函数,子组件通过 props 接收数据或调用父组件传递的回调函数。
// 父组件
function Parent() {
const [data, setData] = useState('Hello');
return <Child message={data} />;
}
// 子组件
function Child({ message }) {
return <div>{message}</div>;
}
子父组件通讯(回调函数)
父组件通过 props 向子组件传递回调函数,子组件调用该函数将数据传递回父组件。
// 父组件
function Parent() {
const handleData = (data) => console.log(data);
return <Child onData={handleData} />;
}
// 子组件
function Child({ onData }) {
return <button onClick={() => onData('Data from child')}>Send</button>;
}
兄弟组件通讯(状态提升)
将共享状态提升到共同的父组件中,通过 props 传递给兄弟组件。
function Parent() {
const [sharedData, setSharedData] = useState('');
return (
<>
<ChildA onData={setSharedData} />
<ChildB data={sharedData} />
</>
);
}
Context API
通过 React 的 Context API 实现跨层级组件通讯,避免逐层传递 props。
const DataContext = createContext();
function App() {
const [data, setData] = useState('Default');
return (
<DataContext.Provider value={{ data, setData }}>
<Child />
</DataContext.Provider>
);
}
function Child() {
const { data, setData } = useContext(DataContext);
return <button onClick={() => setData('Updated')}>{data}</button>;
}
事件总线(Event Bus)
通过自定义事件发布订阅机制实现任意组件间的通讯,适用于非父子关系的组件。
// 事件总线实现
const EventBus = {
events: {},
emit(event, data) {
if (this.events[event]) this.events[event].forEach(cb => cb(data));
},
on(event, callback) {
this.events[event] = this.events[event] || [];
this.events[event].push(callback);
}
};
// 组件A
function ComponentA() {
const handleClick = () => EventBus.emit('event', 'Data');
return <button onClick={handleClick}>Emit</button>;
}
// 组件B
function ComponentB() {
const [data, setData] = useState('');
useEffect(() => {
EventBus.on('event', setData);
}, []);
return <div>{data}</div>;
}
状态管理库(Redux/Zustand)
使用第三方状态管理库(如 Redux、Zustand)集中管理应用状态,实现组件间高效通讯。
// Redux 示例
import { createSlice, configureStore } from '@reduxjs/toolkit';
const dataSlice = createSlice({
name: 'data',
initialState: { value: '' },
reducers: {
update: (state, action) => { state.value = action.payload; }
}
});
const store = configureStore({ reducer: dataSlice.reducer });
function ComponentA() {
return (
<button onClick={() => store.dispatch(dataSlice.actions.update('New Data'))}>
Update
</button>
);
}
function ComponentB() {
const data = useSelector(state => state.value);
return <div>{data}</div>;
}
Refs 和 ForwardRef
通过 ref 直接访问子组件实例或 DOM 节点,适用于需要直接操作子组件的情况。
const Child = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
getData: () => 'Child Data'
}));
return <div>Child</div>;
});
function Parent() {
const childRef = useRef();
const handleClick = () => console.log(childRef.current.getData());
return (
<>
<Child ref={childRef} />
<button onClick={handleClick}>Get Data</button>
</>
);
}
选择建议
- 简单父子通讯:优先使用 props 和回调函数
- 跨层级通讯:使用 Context API
- 复杂状态管理:考虑 Redux 或 Zustand
- 非父子组件通讯:事件总线或状态管理库
- 需要直接访问子组件:使用 refs







