react-redux
的核心是 订阅 store
变化 并 触发组件重新渲染。它利用 React 的 context
和 useSyncExternalStore
来高效地管理状态和 UI 更新。下面详细讲解 react-redux
是如何更新界面的。
🌟 react-redux 更新 UI 的流程
1️⃣ **组件连接 Redux store
**(Provider
共享全局状态)
2️⃣ 组件订阅 store
变化(useSelector
/ connect
监听数据变化)
3️⃣ **状态改变时,触发 store.subscribe
**(Redux dispatch
触发 store
更新)
4️⃣ 对比新旧状态,决定是否重新渲染(避免不必要的 UI 更新)
5️⃣ 通知组件重新渲染(React useState
或 forceUpdate
触发渲染)
🛠 1. Redux store
如何连接到 React
在 react-redux
中,我们通过 Provider
让整个应用访问 store
:
import { Provider } from "react-redux";
import { store } from "./store";
export default function App() {
return (
<Provider store={store}>
<MyComponent />
</Provider>
);
}
Provider
使用 ReactContext
传递store
- 子组件可以用
useSelector
访问 Redux 状态
🛠 2. 组件如何订阅 Redux 状态
组件可以使用 useSelector
订阅 store
里的状态:
import { useSelector } from "react-redux";
function MyComponent() {
const count = useSelector(state => state.counter.value);
return <p>Count: {count}</p>;
}
📌 useSelector
如何监听状态变化?
useSelector
内部会调用store.subscribe()
订阅 Reduxstore
变化- 当
dispatch
修改store
时,所有useSelector
订阅的组件都会执行 useSelector
会对比新旧状态(默认用===
浅比较)- 如果状态没变,组件不会重新渲染,避免不必要的更新
🛠 3. Redux dispatch
如何触发 UI 更新
组件通过 dispatch
触发 Redux store
更新:
import { useDispatch } from "react-redux";
import { increment } from "./counterSlice";
function MyComponent() {
const dispatch = useDispatch();
return <button onClick={() => dispatch(increment())}>+1</button>;
}
📌 dispatch
更新流程
1️⃣ dispatch(action)
触发 Redux store
更新
2️⃣ Redux reducer
计算新 state
3️⃣ store
触发 store.subscribe()
通知所有 useSelector
订阅的组件
4️⃣ useSelector
比较状态,如果变化则触发组件 重新渲染
🛠 4. react-redux
内部是如何订阅 store
的?
🔍 useSelector
的底层实现
在 react-redux
中,useSelector
用 useSyncExternalStore
监听 store
:
import { useSyncExternalStore } from "react";
function useSelector(selector) {
const store = useContext(StoreContext);
return useSyncExternalStore(
store.subscribe, // 订阅 Redux store
() => selector(store.getState()) // 获取最新状态
);
}
📌 useSyncExternalStore
如何工作?
- **订阅
store
**(store.subscribe
) - 检测状态是否变化(通过
store.getState()
获取最新值) - 如果状态变了,触发组件重新渲染(React 重新执行组件)
🔥 Redux 更新 UI 的完整流程
1️⃣ dispatch(action)
触发 store
更新
2️⃣ reducer
计算新 state
3️⃣ store
调用 store.subscribe()
通知组件
4️⃣ 组件的 useSelector
重新执行,并对比状态
5️⃣ 如果状态变化,则 触发 React 重新渲染
🚀 react-redux
UI 更新的优化
✅ 1. 避免不必要的渲染
useSelector
只会让组件更新受影响的状态,而不是整个store
。- 默认使用
===
浅比较,确保状态真的变化才会触发渲染:
const value = useSelector(state => state.value, (a, b) => a === b);
- 如果
useSelector
依赖对象,可以使用reselect
进行 Memoization。
✅ 2. 使用 useCallback
和 useMemo
useDispatch()
生成的dispatch
函数不会变,但useSelector
可能导致组件重新渲染:
const data = useMemo(() => expensiveCalculation(state), [state]);
const handleClick = useCallback(() => dispatch(increment()), [dispatch]);
✅ 3. 代码分片(Lazy Load)
- 使用
redux-toolkit
的lazyReducerEnhancer
进行动态加载reducer
,减少初始化开销。
🎯 总结
步骤 | React Redux UI 更新流程 |
1. 组件连接 |
通过 |
2. 组件订阅状态 |
监听 |
3. 状态变更 |
触发 |
4. 组件重新渲染 |
检测状态变更,触发 UI 更新 |
5. 性能优化 |
只更新受影响的组件,减少不必要渲染 |
React-Redux 通过 useSelector 监听 store,dispatch 触发 store 变更,useSyncExternalStore 检测 state 变化,决定是否重新渲染组件,从而实现高效的 UI 更新。