在React的世界里,组件就像一个个独立的小房间,想要让它们协同工作,"通讯"就成了绕不开的话题。今天我们就来聊聊这些组件之间的"社交技巧",从最基础的"父子传纸条"到高大上的"Redux全球通",让你的组件不再当"孤岛"!
一、父子组件:最简单的直接对话
父子组件通信就像老爸给儿子零花钱------父组件直接在子组件标签上写属性,子组件通过props接收。这种方式简单直接,适合"关系亲近"的组件。
jsx
// 父组件:发钱的爸爸
function Parent() {
const money = 100;
return <Child allowance={money} />;
}
// 子组件:收钱的儿子
function Child(props) {
return <p>爸爸给了我{props.allowance}元零花钱</p>;
}
就这么简单!父组件说啥,子组件就听啥,简直是"父慈子孝"的典范。
二、子父组件:儿子也有话语权
子父组件通信稍微复杂一点,就像儿子要向爸爸汇报考试成绩------父组件需要先创建一个函数,将该函数传递给子组件,子组件调用这个函数并把数据作为参数传回去。
jsx
// 父组件:等待汇报的爸爸
function Parent() {
const [score, setScore] = useState(0);
const receiveScore = (childScore) => {
setScore(childScore);
};
return <Child onScoreChange={receiveScore} />;
}
// 子组件:汇报成绩的儿子
function Child(props) {
const myScore = 95;
return (
<button onClick={() => props.onScoreChange(myScore)}>
爸爸我考了{myScore}分!
</button>
);
}
通过这种"回调函数"的方式,子组件终于有了向父组件"喊话"的能力。
三、兄弟组件:通过爸爸传话
兄弟组件之间通信就像两个小孩要交流,得先告诉爸爸------通过"子传父再父传子"的方式实现。虽然有点绕,但胜在简单直接。
jsx
// 父组件:当传话筒的爸爸
function Parent() {
const [message, setMessage] = useState('');
const receiveFromBrother1 = (msg) => {
setMessage(msg);
};
return (
<>
<Brother1 onSendMessage={receiveFromBrother1} />
<Brother2 messageFromBrother1={message} />
</>
);
}
这种方式适合组件层级不深的场景,但如果组件嵌套太多,就会变成"无限套娃",让人头疼。
四、跨层级组件:用广播喇叭传话
跨层级组件通信就像公司里发通知,不需要每个人都单独说一遍------创建一个全局的Context组件,用Context.Provider包裹子组件,子组件通过useContext函数获取数据。
jsx
// 创建Context:公司广播系统
const CompanyContext = createContext();
// 顶层组件:发通知的老板
function Boss() {
const notice = "明天全体放假!";
return (
<CompanyContext.Provider value={notice}>
<DepartmentManager />
</CompanyContext.Provider>
);
}
// 中层组件:部门经理
function DepartmentManager() {
return <Employee />;
}
// 底层组件:普通员工
function Employee() {
const notice = useContext(CompanyContext);
return <p>收到通知:{notice}</p>;
}
Context就像公司的广播系统,不管你在哪个部门,都能听到老板的通知,完美解决了跨层级通信的问题。
五、任意组件:Redux全球通
如果你的应用特别复杂,组件关系像蜘蛛网一样,那就需要Redux这个"全球通信卫星"了。使用Redux需要三个步骤:
- 安装
@reduxjs/toolkit
(创建仓库)和react-redux
(关联React和Redux) - 创建总仓库,并在其中注册各个子模块
- 使用
useSelector
获取数据,使用dispatch
发送action修改数据
jsx
// 1. 创建仓库
import { configureStore, createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment: (state) => {
state.value += 1;
},
},
});
export const { increment } = counterSlice.actions;
export const store = configureStore({
reducer: { counter: counterSlice.reducer },
});
// 2. 关联React和Redux
import { Provider } from 'react-redux';
import { store } from './store';
function App() {
return (
<Provider store={store}>
<ComponentA />
<ComponentB />
</Provider>
);
}
// 3. 使用Redux
import { useSelector, useDispatch } from 'react-redux';
import { increment } from './store';
function ComponentA() {
const dispatch = useDispatch();
return <button onClick={() => dispatch(increment())}>点我加一</button>;
}
function ComponentB() {
const count = useSelector((state) => state.counter.value);
return <p>当前计数:{count}</p>;
}
通过Redux,任意两个组件都能轻松通信,就像有了全球通卫星电话,再也不用担心"失联"了!
总结:选择合适的通信方式
React提供了多种组件通信方式,从简单的props传递到复杂的Redux,每种方式都有自己的适用场景:
- 父子组件:直接用props
- 子父组件:回调函数
- 兄弟组件:父组件中转
- 跨层级组件:Context
- 复杂应用:Redux
就像现实生活中,跟邻居聊天用敲门,跟远方朋友聊天用微信,选择合适的通信方式,才能让你的React应用运行得更加高效流畅!
希望这篇文章能帮你理解React组件通信的各种方式,让你的组件们不再"各自为战",而是"协同作战"!