在 React 项目中使用 Redux 实现公共下拉选状态共享并通知各组件更新的完整方案如下:
1. 安装 Redux 必要依赖
npm install @reduxjs/toolkit react-redux
2. 创建 Redux Store 和 Slice
store/selectSlice.js
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
value: 'default', // 默认值
options: [
{ value: 'opt1', label: 'Option 1' },
{ value: 'opt2', label: 'Option 2' }
]
};
export const selectSlice = createSlice({
name: 'select',
initialState,
reducers: {
setSelectValue: (state, action) => {
state.value = action.payload;
},
updateOptions: (state, action) => {
state.options = action.payload;
}
}
});
export const { setSelectValue, updateOptions } = selectSlice.actions;
export default selectSlice.reducer;
store/store.js
import { configureStore } from '@reduxjs/toolkit';
import selectReducer from './selectSlice';
export const store = configureStore({
reducer: {
select: selectReducer
}
});
3. 在应用顶层提供 Store
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { store } from './store/store';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
4. 创建公共下拉选组件
components/GlobalSelect.js
import { Select } from 'antd';
import { useDispatch, useSelector } from 'react-redux';
import { setSelectValue } from '../store/selectSlice';
const GlobalSelect = () => {
const dispatch = useDispatch();
const { value, options } = useSelector((state) => state.select);
return (
<Select
value={value}
onChange={(val) => dispatch(setSelectValue(val))}
options={options}
style={{ width: 200 }}
/>
);
};
export default GlobalSelect;
5. 在任意子组件中响应状态变化
components/DisplayComponent.js
import { useEffect } from 'react';
import { useSelector } from 'react-redux';
const DisplayComponent = () => {
const selectValue = useSelector((state) => state.select.value);
useEffect(() => {
console.log('下拉选值变化:', selectValue);
// 这里可以执行数据获取等副作用操作
}, [selectValue]);
return <div>当前选择: {selectValue}</div>;
};
export default DisplayComponent;
6. 在页面中使用(完整示例)
App.js
import GlobalSelect from './components/GlobalSelect';
import DisplayComponent from './components/DisplayComponent';
import AnotherComponent from './components/AnotherComponent';
function App() {
return (
<div style={{ padding: 20 }}>
<h2>公共区域下拉选</h2>
<GlobalSelect />
<div style={{ marginTop: 50 }}>
<h3>组件1</h3>
<DisplayComponent />
</div>
<div style={{ marginTop: 50 }}>
<h3>组件2</h3>
<AnotherComponent />
</div>
</div>
);
}
export default App;
7. 异步数据加载示例(如需要)
// 在需要的地方dispatch异步action
import { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { updateOptions } from '../store/selectSlice';
const DataLoader = () => {
const dispatch = useDispatch();
useEffect(() => {
const fetchOptions = async () => {
const res = await fetch('/api/options');
const options = await res.json();
dispatch(updateOptions(options));
};
fetchOptions();
}, [dispatch]);
return null;
};
关键实现原理说明:
- 状态集中管理:所有下拉选相关状态存储在 Redux store 中
- 单向数据流:
- 下拉选变更 → dispatch action → store 更新 → 所有订阅组件自动更新
- 组件通信:
- 任何组件都可以通过
useSelector
获取最新值 - 任何组件都可以通过
useDispatch
修改值
- 任何组件都可以通过
性能优化建议:
精细化订阅:组件只订阅需要的具体值
// 只订阅value变化(options变化不会触发重渲染) const value = useSelector((state) => state.select.value);
使用memo:对子组件进行记忆化
import { memo } from 'react'; const MemoizedComponent = memo(DisplayComponent);
批量更新:多个状态变更使用
redux-batched-actions
替代方案对比(Redux vs Context)
特性 | Redux | Context API |
---|---|---|
适用场景 | 中大型应用 | 小型应用 |
调试工具 | 强大的Redux DevTools | 无内置工具 |
性能 | 自动浅比较优化 | 需要手动优化 |
学习曲线 | 较高 | 较低 |
异步处理 | 内置Thunk/Saga支持 | 需自行实现 |
对于需要全局共享且频繁更新的状态(如公共下拉选),Redux 仍然是更专业的选择。