面試官:React-Redux 它是怎么更新界面的?
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 更新。