網站首頁 編程語言 正文
一 React-Redux的應用
1.學習文檔
- 英文文檔: https://redux.js.org/
- 中文文檔: https://cn.redux.js.org/
- Github: https://github.com/reactjs/redux
2.Redux的需求
- 狀態的集中管理
- 任意頁面與組件之間的數據傳遞
- 狀態管理的可預測
- 數據的本地化緩存提升性能
說明:
隨著對JavaScript單頁應用程序的要求變得越來越復雜,我們的代碼必須比以前更多地處理狀態。此狀態可以包括服務器響應和緩存數據,以及本地創建的尚未保存到服務器的數據。 UI狀態的復雜性也在增加,因為我們需要管理活動路線,選定標簽,旋鈕,分頁控件等。 管理這個不斷變化的狀態是困難的。
如果一個模型可以更新另一個模型,那么一個視圖可以更新一個模型,該模型會更新另一個模型,而這又可能導致另一個視圖更新。在某種程度上,您不再理解您的應用程序會發生什么情況,因為您已經失去了對其狀態的何時,為何和如何的控制。
當系統不透明且不確定時,很難重現錯誤或添加新功能。 好像這還不夠糟糕,請考慮新的要求在前端產品開發中變得常見。作為開發人員,我們需要處理樂觀的更新,服務器端渲染,在執行路由轉換之前獲取數據等等。
我們發現自己試圖去處理一個我們以前從來沒有處理過的復雜問題,而且我們不可避免地提出這個問題:是放棄的時候了嗎?答案是不。
這種復雜性很難處理,因為我們正在混合兩個對人類頭腦非常難以推理的概念:突變和異步性。我把它們叫做曼托斯和可樂。兩者在分離方面都很出色,但它們一起造成一團糟。像React這樣的庫試圖通過去除異步和直接DOM操作來解決視圖層中的這個問題。但是,管理數據的狀態由您決定。這是Redux進入的地方。
3.什么是Redux
- redux是一個獨立專門用于做狀態管理的JS庫(不是react插件庫)
- 它可以用在react、angular、vue等項目中,但基本與react配合使用
- 作用:集中式管理react應用中多個組件共享的狀態
4.什么情況下需要使用redux
- 總體原則: 大型項目狀態管理復雜才用
- 某個組件的狀態,需要共享
- 某個狀態需要在任何地方都可以拿到
- 一個組件需要改變全局狀態
- 一個組件需要改變另一個組件的狀態
二、最新React-Redux 的流程
安裝Redux Toolkit
# NPM
npm install @reduxjs/toolkit
# Yarn
yarn add @reduxjs/toolkit
創建一個 React Redux 應用
官方推薦的使用 React 和 Redux 創建新應用的方式是使用官方 Redux+JS 模版或Redux+TS 模板,它基于Create React App,利用了Redux Toolkit和 Redux 與 React 組件的集成.
# Redux + Plain JS template
npx create-react-app my-app --template redux
# Redux + TypeScript template
npx create-react-app my-app --template redux-typescript
Redux 核心庫?
Redux 核心庫同樣有 NPM 軟件包,可與模塊捆綁器或 Node 應用程序一起使用,安裝方式如下:
# NPM
npm install redux
# Yarn
yarn add redux
基礎示例
應用的整體全局狀態以對象樹的方式存放于單個store。 唯一改變狀態樹(state tree)的方法是創建action,一個描述發生了什么的對象,并將其dispatch給 store。 要指定狀態樹如何響應 action 來進行更新,你可以編寫純reducer函數,這些函數根據舊 state 和 action 來計算新 state。
import { createStore } from 'redux' /** * 這是一個 reducer 函數:接受當前 state 值和描述“發生了什么”的 action 對象,它返回一個新的 state 值。 * reducer 函數簽名是 : (state, action) => newState * * Redux state 應該只包含普通的 JS 對象、數組和原語。 * 根狀態值通常是一個對象。 重要的是,不應該改變 state 對象,而是在 state 發生變化時返回一個新對象。 * * 你可以在 reducer 中使用任何條件邏輯。 在這個例子中,我們使用了 switch 語句,但這不是必需的。 * */ function counterReducer(state = { value: 0 }, action) { switch (action.type) { case 'counter/incremented': return { value: state.value + 1 } case 'counter/decremented': return { value: state.value - 1 } default: return state } } // 創建一個包含應用程序 state 的 Redux store。 // 它的 API 有 { subscribe, dispatch, getState }. let store = createStore(counterReducer) // 你可以使用 subscribe() 來更新 UI 以響應 state 的更改。 // 通常你會使用視圖綁定庫(例如 React Redux)而不是直接使用 subscribe()。 // 可能還有其他用例對 subscribe 也有幫助。 store.subscribe(() => console.log(store.getState())) // 改變內部狀態的唯一方法是 dispatch 一個 action。 // 這些 action 可以被序列化、記錄或存儲,然后再重放。 store.dispatch({ type: 'counter/incremented' }) // {value: 1} store.dispatch({ type: 'counter/incremented' }) // {value: 2} store.dispatch({ type: 'counter/decremented' }) // {value: 1}
Redux Toolkit 示例
import { createSlice, configureStore } from '@reduxjs/toolkit' const counterSlice = createSlice({ name: 'counter', initialState: { value: 0 }, reducers: { incremented: state => { // Redux Toolkit 允許在 reducers 中編寫 "mutating" 邏輯。 // 它實際上并沒有改變 state,因為使用的是 Immer 庫,檢測到“草稿 state”的變化并產生一個全新的 // 基于這些更改的不可變的 state。 state.value += 1 }, decremented: state => { state.value -= 1 } } }) export const { incremented, decremented } = counterSlice.actions const store = configureStore({ reducer: counterSlice.reducer }) // 可以訂閱 store store.subscribe(() => console.log(store.getState())) // 將我們所創建的 action 對象傳遞給 `dispatch` store.dispatch(incremented()) // {value: 1} store.dispatch(incremented()) // {value: 2} store.dispatch(decremented()) // {value: 1}
三、使用教程
安裝Redux Toolkit和React-Redux?
添加 Redux Toolkit 和 React-Redux 依賴包到你的項目中:
創建 Redux Store?
創建src/app/store.js
文件。從 Redux Toolkit 引入configureStore
API。我們從創建一個空的 Redux store 開始,并且導出它:
app/store.js
import { configureStore } from '@reduxjs/toolkit' export default configureStore({ reducer: {} })
npm install @reduxjs/toolkit react-redux
上面代碼創建了 Redux store ,并且自動配置了 Redux DevTools 擴展 ,這樣你就可以在開發時調試 store。
為React提供Redux Store?
創建 store 后,便可以在 React 組件中使用它。 在 src/index.js 中引入我們剛剛創建的 store , 通過 React-Redux 的<Provider>
將<App>
包裹起來,并將 store 作為 prop 傳入。
index.js
import React from 'react' import ReactDOM from 'react-dom' import './index.css' import App from './App' import store from './app/store' import { Provider } from 'react-redux' ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') )
創建Redux State Slice?
創建src/features/counter/counterSlice.js
文件。在該文件中從 Redux Toolkit 引入createSlice
API。
創建 slice 需要一個字符串名稱來標識切片、一個初始 state 以及一個或多個定義了該如何更新 state 的 reducer 函數。slice 創建后 ,我們可以導出 slice 中生成的 Redux action creators 和 reducer 函數。
Redux 要求我們通過創建數據副本和更新數據副本,來實現不可變地寫入所有狀態更新。不過 Redux ToolkitcreateSlice
和createReducer
在內部使用 Immer 允許我們編寫“可變”的更新邏輯,變成正確的不可變更新。
features/counter/counterSlice.js import { createSlice } from '@reduxjs/toolkit' export const counterSlice = createSlice({ name: 'counter', initialState: { value: 0 }, reducers: { increment: state => { // Redux Toolkit 允許我們在 reducers 寫 "可變" 邏輯。它 // 并不是真正的改變狀態值,因為它使用了 Immer 庫 // 可以檢測到“草稿狀態“ 的變化并且基于這些變化生產全新的 // 不可變的狀態 state.value += 1 }, decrement: state => { state.value -= 1 }, incrementByAmount: (state, action) => { state.value += action.payload } } }) // 每個 case reducer 函數會生成對應的 Action creators export const { increment, decrement, incrementByAmount } = counterSlice.actions export default counterSlice.reducer
將Slice Reducers添加到Store 中?
下一步,我們需要從計數切片中引入 reducer 函數,并將它添加到我們的 store 中。通過在 reducer 參數中定義一個字段,我們告訴 store 使用這個 slice reducer 函數來處理對該狀態的所有更新。
app/store.js
import { configureStore } from '@reduxjs/toolkit' import counterReducer from '../features/counter/counterSlice' export default configureStore({ reducer: { counter: counterReducer } })
在React組件中使用Redux狀態和操作?
現在我們可以使用 React-Redux 鉤子讓 React 組件與 Redux store 交互。我們可以使用useSelector
從 store 中讀取數據,使用useDispatch
dispatch actions。創建包含<Counter>
組件的src/features/counter/Counter.js
文件,然后將該組件導入App.js
并在<App>
中渲染它。
features/counter/Counter.js
import React from 'react' import { useSelector, useDispatch } from 'react-redux' import { decrement, increment } from './counterSlice' import styles from './Counter.module.css' export function Counter() { const count = useSelector(state => state.counter.value) const dispatch = useDispatch() return ( <div> <div> <button aria-label="Increment value" onClick={() => dispatch(increment())} > Increment </button> <span>{count}</span> <button aria-label="Decrement value" onClick={() => dispatch(decrement())} > Decrement </button> </div> </div> ) }
現在,每當你點擊”遞增“和“遞減”按鈕。
- 會 dispatch 對應的 Redux action 到 store
- 在計數器切片對應的 reducer 中將看到 action 并更新其狀態
-
<Counter>
組件將從 store 中看到新的狀態,并使用新數據重新渲染組件
你學到了什么?
這是關于如何通過 React 設置和使用 Redux Toolkit 的簡要概述。 回顧細節:
總結
使用configureStore
創建 Redux store
-
configureStore
接受reducer
函數作為命名參數 -
configureStore
使用的好用的默認設置自動設置 store
為 React 應用程序組件提供 Redux store
- 使用 React-Redux
<Provider>
組件包裹你的<App />
- 傳遞 Redux store 如
<Provider store={store}>
使用createSlice
創建 Redux "slice" reducer
- 使用字符串名稱、初始狀態和命名的 reducer 函數調用“createSlice”
- Reducer 函數可以使用 Immer 來“改變”狀態
- 導出生成的 slice reducer 和 action creators
在 React 組件中使用 React-ReduxuseSelector/useDispatch
鉤子
- 使用
useSelector
鉤子從 store 中讀取數據 - 使用
useDispatch
鉤子獲取dispatch
函數,并根據需要 dispatch actions
原文鏈接:https://blog.csdn.net/xm1037782843/article/details/127606426
相關推薦
- 2023-01-17 關于最大池化層和平均池化層圖解_python
- 2022-03-26 Unity實現坦克模型_C#教程
- 2022-03-27 C++浮點數在內存中的存儲詳解_C 語言
- 2023-12-08 table 單元格垂直居中
- 2022-05-03 python中的Pytorch建模流程匯總_python
- 2023-07-26 webpack中plugin的工作原理
- 2022-07-08 Python?3.x對.CSV數據按任意行、列讀取的過程_python
- 2022-06-02 jquery實現界面點擊按鈕彈出懸浮框_jquery
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支