摘要:你當然很高興了。如你所見以及從經驗中了解到的在上面的圖表中,數據能夠雙向流動。改變了一些值,并將值返還給,然后刷新了。注意是如何通過導出的。原創新書移動前端高效開發實戰已在亞馬遜京東當當開售。
作者:珂珂(滬江前端開發工程師)
本文原創,轉載請注明作者及出處。
原文地址:https://hackernoon.com/thinki...
當我們在Spoil打算推出我們自己的移動端應用時,頭一個需要作出的決定就是:我們應該使用哪種編程語言?經過一番討論,我們最終做出的決定是:React-Native。學習一門新的“語言”或者框架并不是個大問題,但是老兄我得告訴你,React-Native和Redux確確實實是塊難啃的骨頭。這篇文章沒有介紹React-Native是如何工作的(因為那確實不是最難的部分)。下面幾段文字的目的在于幫助任何人完成從“Thingking in MVC”到“Thinking in Redux”的轉換。希望能對你有所幫助。
React-Natvie 和 Redux?一旦你開始學習React-Natvie(或React),在有人向你提及Redux之前,你大概只落后了3個stack overflow的問題,或者medium.com上幾篇博客的距離。
你當然很高興了。你開始理解state和props的區別了,你知道了componentDidMount是干啥的了,你甚至懂得了怎樣合理地創建一個可復用組件。但是忽然間,你發現自己到了egghead.io網站上,這里的一些家伙正討論著stores、reducer compositions、action,還有將state映射到props。
你同時也意識到,之前你可以這么做:
$(“.my-button”).click();
讓一個按鈕干點什么;現在?3個小時可能你的一個按鈕啥也干不了。
作一些類比如果你是從MVC(或者MVVC)的世界過來的,你習慣了使用models,views和controllers。但是在Redux中,我們用actions、reducers、stores和components來解決問題。從MVC“遷移”到Redux是比較困難,但這里是我的做法:
Actions = Controller
把你的Actions想象成controller。無論何時你想讓你的App產生一些活動的時候(比如:載入數據、將isLoading標志從true變為false等等),那么你需要分發一個action。就像在MVC中,你需要調用一個controller。
Reducer = Model
某種程度上吧。你的reducers將會掌管應用程序的當前狀態(比如: 用戶信息、api載入的數據、需要展示的數據)。當一個action被調用時,reducer來決定需要做些什么。在MVC中你可能有一個帶setName()方法的model,在Redux中,你將會有一個reducer,它負責處理一個action,并將name設置到state中去。
特別感謝 Prabin Varma*。將store講的更生動形象。
Stores = ???
store在Redux中很特別,在MVC中難以找和它等價的東西。但是不用擔心。store是深藏在幕后被小心保管的東西,就像是一個容器,存儲了所有為state服務的reducer集合。它有一個方法來獲得當前的狀態,并且暴露出方法來訂閱state的變動(使用“connect()”方法)。這就是Redux允許你調用action,并能將它們像props一樣傳入組件的秘密了。
Components = Views
組件是有些類似于你的智能視圖。它們負責展示你從state中拿到的信息。我建議將你的組件分為兩部分:一部分只是作為展示部分(木偶組件),另一部分負責處理所有的action和state變更(智能組件)。
從MVC思想轉換至Redux思想MVC和Redux之間一個主要的不同點就是:MVC中的數據能夠雙向流動,但在Redux中,數據被限制為只能單向流動。
經典MVC。那時的人生還沒有如此艱難。
如你所見(以及從經驗中了解到的)在上面的圖表中,數據能夠雙向流動。你在view層按下了一個button,它會向你的controller發送一個信息,導致model的更新。model改變了一些值,并將值返還給controller,然后controller刷新了view。灰常簡單!
Redux數據流。人生變得糟透了。
在Redux中事情有些不同。假如你有一個組件,然后你想在按鈕被按下的時候做些事情。那么你該從何開始呢?我是這么做的:
定義你的Action
定義你的Reducer
在你的Component中將Actions像props一樣定義
把它們放到View上
下面是個解釋以上概念的簡單代碼示例。在這個例子中,我將會展示如何編輯一個text input,然后當有用戶按下按鍵時它將會調用action來保存內容。
首先,從Action文件開始
export const MODIFY_NAME = "MODIFY_NAME"; export const SAVE_NAME = "SAVE_NAME"; /** * 這是當用戶按下按鍵的時候,我們從組件上所調用的action。 用戶每輸入一個字符,都會帶著input中新的value值去調用這個action。 注意函數中的type和payload字段,我們將在reducer中用到它們,去用新的value值“修改”我們的model。 **/export function modifyName(name){ return { type: MODIFY_NAME, payload:{ name } } } /** 這是當用戶按下保存姓名按鈕的時候,我們從組件上所調用的action。 注意我們是如何將value傳入的。這么做是因為reducer已經持有了該value值。 另外,這里也沒有payload。這么做的原因是因為reducer并不需要。在reducer那一步中,不需要額外的信息。 同時,一般這么做將調用一個api終端以及諸如此類的東西,但是為了簡潔,我沒有將其包含進來。 **/export function saveName(){ return{ type: SAVE_NAME } } 現在看我們的Reducer。總的來說,reducer需要處理傳入的actions。 // 導入我們早先定義好的actions文件 import * as constants from "../actions.js"; /** 初始狀態被用來定義你的reducer。 通常你將會把它設置為默認值和空字符串。需要這么做的理由是,當要使用這些值的時候,你至少保證它們有一個默認值。把它當做一個默認構造器吧。 **/const initialState = { name:"", isSaved: false } /** 這個reducer是負責“監聽”輸出的action。我們早些定義的saveName和modifyName函數,將會在這里被調用。action參數則是上面函數中定義的將要被return出來的值(type和payload)。 **/function reducer(state=initialState,action){ switch (action.type){/** 在Redux中state是不可變的。你必須時刻返回一個新的,所以這里使用ES6的展開運算符將傳入的state中的值拷貝過來。 **/ case constants.MODIFY_NAME: return { ...state, name:action.payload.name } case constants.SAVE_NAME: return { ...state, isSaved:!state.isSaved } } } export default name;
注意到constants.MODIFY_NAME 和 constants.SAVE_NAME 是如何與我們在action中將要返回出來的對象的type字段對應上的。正是以這種方式,reducer才能得知action的身份。
現在來定義我們的“智能”組件。這意味著這個組件將會定義所有對action的調用。
/** App首頁 **/ ‘use strict’; import React, { Component } from ‘react’; import { connect } from ‘react-redux’; import Name from ‘./presentational/Name’; import * as actions from ‘./actions/name’; /** 實際的值(name和isSaved)和調用action所需的function都以props的形式傳入。**/ class NameContainer extends Component { render() { return (); } } /** 這么做是為了得到reducer中保存的值,并且把它們返回給component。這樣我們才能通過this.props來調用它們 **/ const mapStateToProps = (state,ownProps) =>{ /** 使用Redux的stores,它允許我們僅僅通過state.name來獲得reducer中的值。注意name是如何通過reducer導出的。 **/ const { name, isSaved } = state.name; return {name,isSaved }; } /** 在mapStateToProps函數中,我們將state中的變量映射成property來傳入我們的展示組件。在mapDispatchToProps函數中,我們將action處理函數映射到我們的容器,這樣我們就能將它們傳入到展示組件中去了。 **/ const mapDispatchToProps = (dispatch) => { return { modifyName:(name)=>{ dispatch(actions.modifyName(name)) }, saveName:()=>{ dispatch(actions.saveName()) }, } /** 如你所見,我們能夠將函數和變量以props的方式傳入我們的容器全依賴于此。是react-redux中的connect函數神奇的實現了這些功能。 **/ export default connect(mapStateToProps,mapDispatchToProps)(NameContainer);
現在到了最簡單的部分,創建一個與用戶交互的展示組件(MVC里的V)。
/** * 木偶組件將會使用傳入的props,這些是用戶的行為在智能組件上產生的數據 */‘use strict’; import React, { Component } from ‘react’; import {Text,TextInput, TouchableOpacity} from ‘react-native’; import { Actions, ActionConst } from ‘react-native-router-flux’; class Name extends Component render() { return (); } } export default Name; this.props.modifyName(name)} /> {this.props.saveName()}> Save
就是這樣了!雖然你仍然需要做一些基礎的的模版設置填充,但是我希望這解釋清楚了如何以redux的方式進行思考。
有些問題曾經讓我掉到坑里一段時間(比如:信息傳到了哪?怎么傳的),因此我希望節省你們的時間,減輕你們的頭疼。
如果你希望看到我們團隊使用React-Native 和 Redux搭建出來的app是什么樣的,那么在這兒查看我們的app吧(https://spoil.co/app)。
iKcamp原創新書《移動Web前端高效開發實戰》已在亞馬遜、京東、當當開售。
>> 滬江Web前端上海團隊招聘【Web前端架構師】,有意者簡歷至:zhouyao@hujiang.com <<
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/91741.html
摘要:本文翻譯自首發于處理異步利器眾成翻譯作者行魏可知鏈接來源知乎著作權歸作者所有。幾天前,我和同事談了談如何管理異步操作。是基于和生成器函數,輔助我們快速組織所有異步分散的操作。 本文翻譯自: https://medium.freecodecamp.c... 首發于: 處理異步利器 -- Redux-saga (眾成翻譯) 作者:行魏可知鏈接:https://zhuanlan.zhihu....
摘要:自己英語一般,水平有限,獻上原文地址,還有我翻譯的中文地址,歡迎大家勘誤下面是自己的一點感想先說一下,我們知道,前端優化有這么幾步,第一步首先呢我們知道,一個應用要依賴好多條文件,而瀏覽器加載完一條,要執行完這條才加載下一條,所以呢,就很慢 自己英語一般,水平有限,獻上原文地址,還有我翻譯的中文地址,歡迎大家勘誤 下面是自己的一點感想 先說一下webpack,我們知道,前端優化有這么幾...
摘要:是分發器,是數據與邏輯處理器,會在注冊針對各個命令字的響應回調函數。當按如下方式觸發回調時,回調函數具備事件的特性。 本系列博文從 Shadow Widget 作者的視角,解釋該框架的設計要點。本篇解釋 Shadow Widget 在 MVC、MVVM、Flux 框架之間如何做選擇。 showImg(https://segmentfault.com/img/bVOODj?w=380&h...
摘要:前端日報精選專題之惰性函數中的執行上下文和調用棧是什么個人總結新特性緩存機制詳解技術內幕的秘密中文第期給前端工程師講設計終篇行代碼搭建神經網絡知乎專欄版模塊,桌面支付請求,,以及眾成翻譯你應該知道的知乎專欄技術周刊同步代碼書寫異 2017-08-22 前端日報 精選 JavaScript專題之惰性函數JavaScript 中的執行上下文和調用棧是什么?個人總結(css3新特性) HTT...
閱讀 2791·2021-11-17 09:33
閱讀 4455·2021-09-22 15:57
閱讀 2866·2019-08-30 14:16
閱讀 3133·2019-08-29 14:07
閱讀 2413·2019-08-26 11:55
閱讀 3415·2019-08-23 17:07
閱讀 1725·2019-08-23 16:50
閱讀 2535·2019-08-23 16:08