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