摘要:日常項目直接使用是完全沒有問題的,可是隨著項目的日益壯大,組件數量的逐漸增長,組件之間的嵌套使得數據的管理越來越繁重。最后數據保存進了中的,頁面也會根據的改變自動更新。
以下文章均為個人近期所學心得,自學react、redux,逐漸找到自己的方向,現將自己的方向方式寫出來,以供大家學習參考,肯定會有不足,歡迎批評指正。
日常項目直接使用react是完全沒有問題的,可是隨著項目的日益壯大,組件數量的逐漸增長,組件之間的嵌套使得數據的管理越來越繁重。
純react項目,每個組件自己維護自己的state,父子組件之間通信、兄弟組件通信也都可以做到,只不過隨時項目代碼量的增加后期會變得難以維護,所以使用redux這種數據管理是很有必要的,而且也是自我技術水平提高的一個很好方向。
本文專注功能實現、使用流程,所以可能細節問題點闡述的不夠深,不過個人覺得用于初學者使用并且達到想要的功能應該可以滿足了。
首先原理(純白話):
頁面操作(點擊啊什么的)觸發action -->
action做一層處理后觸發reducer -->
reducer中定義全局的唯一的store中的state+存入的方法(必須是純函數,也就是說你傳入什么參數就輸出相應的結果,不可以根據實時時間戳啊等類似的方法產出不同的值。) -->
最后數據保存進了store中的state,頁面也會根據state的改變自動更新。
基本: Provider:具體概念不贅述,想細研究的自行度娘,這里只說明放在根組件的最外層并將store傳遞進去
代碼(登錄功能流程):
// 使用react-redux中的connect方法 import { connect } from "react-redux"; // 導入我們定義的action import { saveUserinfo } from "@/Reducers/Pages/actions"; // 使用connect包裹我們的state和action,這里有兩個方法(mapStateToProps、mapDispatchToProps),具體概念自行度娘 // 組件結尾導出處 export default connect(mapStateToProps, mapDispatchToProps)(Login); // 可以寫成 export default connect(state => ({ // 如果你的組件需要使用store中的state,就在這里引入你所以要使用的reducer函數名 }), { // 這里引用你當前組件所需要使用的所有action方法 saveUserinfo })(Login); // 按鈕提供一個點擊事件 // sumitForm方法 sumitForm = () => { var username = this.refs.username.value; var password = this.refs.password.value; // 發送ajax請求,這里我封裝一層,很簡單,可以直接寫ajax請求,主要點在請求成功的回調里 LoginFunc(username,password) .then(res => { // 請求成功后的數據 var data = res.data; // 這里就是觸發action的地方,只需要將我們需要的數據作為參數傳進去就好 this.props.saveUserinfo(data); this.props.history.push("/index"); }) }
以上就是我們在組件中觸發action的過程,到這里你就可以將接口返回來的數據傳遞給action了
// 定義action時需要先定義action-type,作用就是關聯action和reducer,action想要觸發reducer那么只需要使用定義的type就可以,不需要去引用reducer,這樣別人在看我們的代碼時,看type就知道這一塊有哪些功能了,具體的注釋也可以寫在type中。 // type很簡單 // 保存用戶信息 export const SAVEUSERINFO = "SAVEUSERINFO";
action代碼
// 導入type import * as Pages from "./action-types"; // 保存用戶表單數據 export const saveUserinfo = (data) => { // 這個傳進來的data就是我們剛剛在組件中傳遞進來的后端返回數據 // 這里直接returntypes,并將data傳遞過去 return { type: Pages.SAVEUSERINFO, data } }
這里就是action,我們可以將組件中的后端請求寫在action里,只需要返回的時候觸發type并將數據傳遞過去就好
下面我們看reducer
// 之前說了,action只需要觸發type就可以觸發reducer了 // 所以reducer中同樣需要引入reducer import * as Pages from "./action-types"; // 在reducer中我們需要定義state,也是就是唯一store中的state let defaultValue = { session_id: "", user_name: "", user_id: "", is_login: false, initialization: "", org_name: "" } // reducer中就是將action傳遞過來的數據保存到store中的state里 // 兩個參數,第一個是state,第二個是action傳遞過來的數據,包含type和數據,通過type值判斷執行那個函數,這里只定義了一個type export default function UserInfo (state = defaultValue, action = {}) { switch (action.type) { // 這個就是type也就是action和reducer關聯的type case Pages.SAVEUSERINFO: return { ...state, // 這里就是將action傳遞過來的數據保存到我們的store中 ...{ session_id: action.data.data.session_id, user_name: action.data.data.name, user_id: action.data.data.id, is_login: true, initialization: action.data.data.initialization, org_name: action.data.data.org_name } }; default: return state; } }
以上就完成了我們從后端拿數據,保存到store中的所有流程。
// 保存到了store中后,我們頁面的所有組件都可以拿這里邊的數據, // 同樣,我們組件中用到數據的地方會根據store中數據的改變而改變,也就是說我們想要改變頁面的狀態,唯一的辦法就是觸發action完成以上步驟。
到這里我們還沒有結束,需要我們形成閉環,也就是怎么將store存入我們的Provider
// 我這里是將store拆分了,按功能去拆分的,具體可以看每個人的習慣去拆分
我的目錄結構,可根據具體項目區自定自己的目錄結構
// 有拆分就要有合并,所以我們要在存入Provider之前進行reducer的合并 // 這里使用redux提供的方法combineReducers import { combineReducers, } from "redux"; import UserInfo from "./Pages/reducers"; const rootReducer = combineReducers({ UserInfo, // 一些其他功能的reducer // UserStaffDirectory, // addUserMsgReducer }); // 導出統一的reducer export default rootReducer;
插一句,以上就已經完成了基本功能,這里我在多加一項功能,就是數據持久化,也就是我們數據存到store中但是會存在一個刷新數據丟失的問題,這樣很不利與我們項目的使用,所以我加入一個新的庫,來保證我們的數據是可持久化的,這里使用redux-persist庫
數據持久化
// 首先導入redux的一些方法 import { createStore, applyMiddleware } from "redux"; // 還使用了thunk,還沒來的及去研究,這里先使用吧 import thunk from "redux-thunk"; // 引入redux-persist import { persistStore, persistReducer } from "redux-persist"; import { PersistGate } from "redux-persist/es/integration/react"; import storage from "redux-persist/es/storage" // 首先定義一個對象(按官方文檔來的,沒具體研究) const persistConfig = { key: "root", storage, }; // 將我們的合并后的reducer引入 import Reducers from "@/Reducers"; // 使用redux-persist合并 const persistedReducer = persistReducer(persistConfig, Reducers) // 定義一個函數,返回persistor和store,讓我的組件使用 function configureStore(){ // 這里我使用了thunk,具體原理我也沒去細研究,使用redux的createStore去合并,最終產出我們需要傳入Provider的store let store = createStore(persistedReducer, applyMiddleware(thunk)); // 這里就是應用redux-persist以完成數據持久化 let persistor = persistStore(store); return { persistor, store } } // 組件render中 const render = Component => { // 引入 const { persistor, store } = configureStore(); ReactDOM.render( // 將store傳入跟組件// 數據持久化 , document.getElementById("app"), ) }// 所有子組件
以上就完成了全部循環,組件發起action,觸發reducer,保存數據到store中,組件被更新。
只有存的步驟,不能沒有取,對吧,上文中實現了登錄功能,并且將后端返回的數據保存到store中,現在我們將store中的數據拿出來展示在界面上。
登錄請求成功后后端會返回用戶名,用戶ID等信息,我們已經將其保存到了store中,下面看我們的header組件將引用我們store中的用戶名。
不需要我們引入過多的文件,只需要在組件結尾處的方法mapStateToProps加入我們要的reducer函數名即可
const mapStateToProps = state => ({ UserInfo: state.UserInfo }) export default connect(mapStateToProps,({}))(Header); // 組件中使用 this.props.UserInfo.user_name // 即可取值 // 同時呢,我們改變了store中的user_name那么我們取值的地方也會動態更新。
以上就是本文全部內容,如有發現不足,或錯誤之處,煩請指正。
轉載請注明出處,SF大洋首發。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/96726.html
摘要:而函數式編程就不一樣了,這是模仿我們人類的思維方式發明出來的。數據流在中,數據的流動是單向的,即從父節點傳遞到子節點。數據流嚴格的單向數據流是架構的設計核心。 前言 總括: 本文采用react+redux+react-router+less+es6+webpack,以實現一個簡易備忘錄(todolist)為例盡可能全面的講述使用react全家桶實現一個完整應用的過程。 代碼地址:Re...
摘要:接下來演示不變性打開終端并啟動輸入。修改代碼如下我們使用在控制臺中打印出當前的狀態。可以在控制臺中確認新的商品已經添加了。修改和文件最后,我們在中分發這兩個保存完代碼之后,可以在瀏覽器的控制臺中檢查修改和刪除的結果。 典型的Web應用程序通常由共享數據的多個UI組件組成。通常,多個組件的任務是負責展示同一對象的不同屬性。這個對象表示可隨時更改的狀態。在多個組件之間保持狀態的一致性會是一...
摘要:宅印前端基于的模式開發,我們指定了一套分工明確的并行開發流程。下面通過一個蘋果籃子實例,來看看整個應用開發流程。容器負責接收中的和并發送大多數時候需要和直接連接,容器一般不需要多次使用,比如我們這個應用的蘋果籃子。 前言:在當下的前端界,react 和 redux 發展得如火如荼,react 在 github 的 star 數達 42000 +,超過了 jquery 的 39000+,...
閱讀 2848·2023-04-26 01:02
閱讀 1874·2021-11-17 09:38
閱讀 798·2021-09-22 15:54
閱讀 2905·2021-09-22 15:29
閱讀 893·2021-09-22 10:02
閱讀 3444·2019-08-30 15:54
閱讀 2011·2019-08-30 15:44
閱讀 1601·2019-08-26 13:46