Redux
Redux是一個流行的JavaScript狀態管理庫,通常用于React等前端框架結合使用。Redux 的設計思想是讓應用的狀態變得可預測、可追蹤、易于調試和測試。
Redux的核心l理念
- 單一數據源:整個應用的狀態被存儲在一個
唯一的Store
對象中,所有組件都從這個Store
讀取數據 - 狀態只讀:唯一改變狀態的方法時觸發action,不能直接修改state
- 使用純函數來執行修改:Reducer處理器是函數,接收當前的store和action,返回新的state,不產生副作用
Redux的核心概念
Store
:是Redux的核心,它是一個包含整個應用程序狀態的對象。Redux應用只有一個單一的Store,通過createStore
函數創建。提供了以下的方法
-getStore()
:獲取當前狀態
-dispatch(action)
:觸發狀態更新
-subscribe(listener)
:監聽狀態變化Action
:一個普通的JavaScript對象,用于描述狀態的變化,它必須有type
字段,表示動作的類型,可以有其他自定義數據
const incrementAction = {type: 'INCREATE',payload: 1
}
Reducer
::是一個純函數,接受當前state
和action
作為參數,并返回一個新的狀態。Reducer必須保持純函數特性,既不直接修改原狀態,而是返回一個新的狀態對象
function counterReducer(state = 0,action){switch(action.type){case 'INCREATE':return state + action.payload;default:return state}
}
Dispatch
:用于觸發action,通過調用store.dispatch(action)
。React會將action傳遞給Reducer,從而更新狀態Subscribe
:訂閱Store的狀態,通常用于UI更新
Redux的工作流程
- 組件通過
dispatch
發送一個action
Store
接收到action
,調用reduce
Reducer
根據action
的類型和數據,返回新的state
Store
更新state
,通知訂閱的組件重新渲染
React Redux
React Redux是官方推薦的React與Redux結合使用的庫,主要作用是讓React組件可以方便的訪問和操作Redux的全局狀態。它極大的簡化了React項目中全局狀態的管理和組件間的數據通信
React Redux的核心功能
Provider
組件:用于將Redux
的store
注入到整個React
應用中。只需在應用的根組件外包裹一次,所有的子組件都能訪問到Redux
的狀態
import { Provider } from 'react-redux'
import { store } from './store'
<Provider store={ store }><App />
</Provider>
useSelector
:在函數組件獲取Redux store
里的狀態;只會在依賴的狀態變化時自動觸發組件重新渲染
import { useSelector } from 'react-redux'
const menuIndex = useSelector(state => state.head.menuIndex)
useDispatch
:獲取dispatch
方法,用于分發action
,觸發reduce更新狀態
import { useDispatch } from 'react-redux'
const dispatch = useDispatch()
dispatch({type: 'SET_MENU', payload: 1})
connect
(高階組件):用于將Redux
的state
和dispatch
方法“連接”到React
組件的props
上。它主要用于類組件或早期函數組件
(在hooks出現之前),現在雖然推薦使用useSelector
和useDispatch
,但connect依然在很多老項目和復雜場景下被廣泛使用
import { connect } from ‘react-redux’// 1、映射 state 到 props
const mapStateProps = (state) => ({menuIndex: state.head.menuIndex
})// 2、映射 dispatch 到 props
const mapDispatchProps = (dispatch) => ({setMenu: (index) => dispatch({type: 'SET_MENU'})
})// 3、用connect包裹組件
class MyComponent extends React.Component {render(){const { menuIndex, setMenu } = this.propsreturn (<div><span>{menuIndex}</span><button onClick={() => setMenu(1)}>切換菜單</button></div>)}
}
export default connect(mapStateProps, mapDispatchProps)(MyComponent)
React Redux的工作流程
- 創建Store:使用
createStore
或configureStore
創建React store,并定義初始狀態和reducer - 提供Store:通過
Provider
將store注入到React應用中 - 連接組件:使用
connect
或Hooks API(useSelector
、useDispatch
)將組件與React store連接,獲取狀態和操作 - 更新狀態:組件通過
dispatch
操作觸發狀態更新,Redux根據reduce更新store的狀態 - 重新渲染:組件根據新的狀態重新渲染,完成UI更新
react-persist
react-persist是一個用于持久化Redux狀態的庫,它的作用是:把Redux store中的數據自動保存到本地存儲(如localStorage、sessionStorage、IndexedDB等),頁面刷新或關閉后再打開,狀態依然能恢復
基本使用
- 安裝:
npm install redux-persist
- 配置
/** @format* createStore: 創建redux store* persistStore :持久化redux store* persistCombineReducers: 持久化多個reducer* storage:使用瀏覽器的lcaolStorage作為持久化存儲介質*/
import { legacy_createStore as createStore } from 'redux'
import { persistStore, persistCombineReducers } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // 默認 localStorageimport user from './reducers/user'
import head from './reducers/head'const persistConfig = {key: 'root', // 本地存儲的key名storage, //存儲方式 也可以用 sessionStorage 或自定義// whitelist: 只持久化那些reducer// blacklist:不持久化哪些reducer}
// 將多個reduce合并
const reducers = { user, head }
// 創建持久化存儲的reducer
const persistedReducer = persistCombineReducers(persistConfig, reducers)
const store = createStore(persistedReducer)
const persist = persistStore(store)export { store, persist }
- 在React 項目入口文件使用
/*** PersistGate:用于在 React 應用中延遲渲染 UI,直到 Redux 持久化的數據恢復完成。* 當你用 redux-persist 持久化 Redux 狀態時,頁面刷新后需要先從本地存儲(如 localStorage)恢復數據。* PersistGate 會在數據還原完成前,先渲染 loading 指定的內容(比如 loading 動畫或 null),等數據恢復好后再渲染你的應用。*/
import { Provider } from ‘react-redux’
// PersistGate 組件會在狀態恢復完成后再渲染應用,避免“閃屏”
import { PersistGate } from 'redux-persist/integration/react'
import { store, persist } from './store'<Provider store={store}>// persistor={persist} 是redux-persist創建的持久化控制對象<PersistGate loading={null} persistor={persist}></PersistGate>
</Provider>
注意事項
- 存儲限制:localStorage 和 sessionStorage 有存儲大小限制(通常為 5MB),對于較大的狀態數據,可能需要考慮其他存儲方案
- 安全性:敏感數據(如用戶憑證)不應直接存儲在 localStorage 中,建議使用加密或其他安全措施。
- 性能優化:對于頻繁更新的狀態,持久化操作可能會影響性能,建議通過白名單或黑名單進行優化。