react-native項(xiàng)目中從零開始使用redux

本文主要是以我的另一篇文章的思維過程來操作,希望大家使用后可以記住整個(gè)過程,從而活學(xué)活用,使用到自己的項(xiàng)目中.

參考文章:react-native中使用redux的原理分析及demo

demo地址:github.com/NextChampion/react-native-redux-navigation-example

react native 已更新到0.57.8版本

效果圖


效果圖

demo簡(jiǎn)單介紹:

功能:登錄頁(yè)中點(diǎn)擊登錄,跳轉(zhuǎn)到主頁(yè),主頁(yè)內(nèi)含有一個(gè)大家都很熟悉的counter組件.可以實(shí)現(xiàn)簡(jiǎn)單的加減數(shù)操作;

demo邏輯:

登錄:

點(diǎn)擊登錄時(shí),組件的點(diǎn)擊方法會(huì)發(fā)送消息到action內(nèi),

action將該消息預(yù)處理,即區(qū)分一下type,然后返回給store,

store將分好類的消息,分配到reducer中處理state.

reducer接收到帶有type的消息以后,找到對(duì)應(yīng)的處理辦法,生成新的state返回給store,

store控制頁(yè)面渲染,跳轉(zhuǎn)到主頁(yè);

加減:

點(diǎn)擊加號(hào),組件將該點(diǎn)擊方法發(fā)送到action內(nèi),

action預(yù)處理該消息,區(qū)分是加/減,指定type后,返回消息給store;

store收到預(yù)處理后的消息后,將該消息發(fā)送給reducer;

reducer收到store發(fā)過來的消息,根據(jù)消息內(nèi)的type處理數(shù)據(jù),真正進(jìn)行加/減過程,并且將新的state返回給store;

store收到reduder發(fā)過來的新state,控制頁(yè)面渲染,即頁(yè)面中數(shù)字的變化;

demo特點(diǎn):

1.區(qū)分登錄和加減邏輯,并且將不同的state對(duì)應(yīng)不同的組建部分

登錄相關(guān)的state只有l(wèi)oginPage可用,加減相關(guān)的state只有主頁(yè)面可用;

2.頁(yè)面切換使用react-navigation控制;

3.該demo大家可以拿去改改部分代碼,直接類比內(nèi)部redux的邏輯實(shí)現(xiàn)過程,開發(fā)自己的項(xiàng)目;

下面開始詳細(xì)講解整個(gè)demo的實(shí)現(xiàn)過程

1.新建項(xiàng)目


react-native init CountersDemo

2.安裝redux相關(guān)文件


npm install --save redux

npm install --save react-redux

npm install --save react-navigation

npm install --save redux-thunk

3.建立項(xiàng)目?jī)?nèi)部文件夾


4.redux相關(guān)代碼實(shí)現(xiàn)過程

1)新建src文件夾存放所有js文件.

2)新建constants,actions,reducers,store,container,pages文件夾

3)(設(shè)定類型type) constans文件夾內(nèi)新建文件loginType,用來劃分登錄過程中的事件類別


export const LOGIN_IN_DOING = 'LOGIN_IN_DOING'; //正在登陸

export const LOGIN_IN_DONE = 'LOGIN_IN_DONE'; // 登陸完成

export const LOGIN_IN_ERROR = 'LOGIN_IN_ERROR'; // 登陸出錯(cuò)

4.(設(shè)定預(yù)處理消息過程)actions文件夾內(nèi),新建loginAction文件,用來給預(yù)處理消息區(qū)分各個(gè)事件的類別


'use strict';

import * as types from '../constants/loginTypes';// 導(dǎo)入事件類型,用來做分配給各個(gè)事件

// 模擬用戶信息

let user = {

name: 'zhangsan',

age: 24,

}

// 訪問登錄接口 根據(jù)返回結(jié)果來劃分action屬于哪個(gè)type,然后返回對(duì)象,給reducer處理

export function login() {

console.log('登錄方法');

return dispatch => {

dispatch(isLogining()); // 正在執(zhí)行登錄請(qǐng)求

// 模擬用戶登錄

let result = fetch('https://www.baidu.com/')

.then((res)=>{

dispatch(loginSuccess(true,user)); // 登錄請(qǐng)求完成

}).catch((e)=>{

dispatch(loginError(false)); // 登錄請(qǐng)求出錯(cuò)

})

}

}

function isLogining() {

return {

type: types.LOGIN_IN_DOING

}

}

function loginSuccess(isSuccess, user) {

console.log('success');

return {

type: types.LOGIN_IN_DONE,

user: user,

}

}

function loginError(isSuccess) {

console.log('error');

return {

type: types.LOGIN_IN_ERROR,

}

}

5.(設(shè)定消息的具體處理過程)reducers文件夾內(nèi)新建loginReducer文件,用來處理登錄過程中的state變化


'use strict';

import * as types from '../constants/loginTypes'; // 導(dǎo)入事件類別,用來做事件類別的判斷

// 初始狀態(tài)

const initialState = {

status: '點(diǎn)擊登錄',

isSuccess: false,

user: null,

}

// 不同類別的事件使用switch對(duì)應(yīng)處理過程

export default function loginIn(state=initialState, action) {

switch (action.type) {

case types.LOGIN_IN_DOING:

return {

...state,

status: '正在登陸',

isSuccess: false,

user: null,

}

break;

case types.LOGIN_IN_DONE:

return {

...state,

status: '登陸成功',

isSuccess: true,

user: action.user,

}

break;

case types.LOGIN_IN_ERROR:

return {

...state,

status: '登錄出錯(cuò)',

isSuccess: true,

user: null,

}

break;

default:

return state;

}

}

6).項(xiàng)目?jī)?nèi)可能并不是只有一個(gè)redux操作邏輯,現(xiàn)在給所有的reducer建立一個(gè)統(tǒng)一的入口

reducers文件夾內(nèi)新建index.js文件,作為統(tǒng)一入口;

(由于本篇文章是demo寫好后整理的,所以現(xiàn)在這里不應(yīng)該有counterReducer,大家在參考本文時(shí),這里只寫login的內(nèi)容即可)


'use strict';

import { combineReducers } from 'redux';

import loginIn from './loginReducer'; // 導(dǎo)入登錄的redux處理過程

const rootReducer = combineReducers({ // 將所有的redux處理邏輯包裝在一起

loginIn: loginIn,

});

export default rootReducer; // 導(dǎo)出,作為統(tǒng)一入口

7).創(chuàng)建項(xiàng)目中的store,用來管理所有的state

store文件夾內(nèi)新建ConfigureStore.js文件


'use strict';

import { createStore, applyMiddleware } from 'redux';

import thunkMiddleware from 'redux-thunk';

import rootReducer from '../reducers/index';

const createStoreWithMiddleware = applyMiddleware(thunkMiddleware)(createStore);

export default function configureStore(initialState) {

const store = createStoreWithMiddleware(rootReducer, initialState)

return store;

}

8).現(xiàn)在action,reducer,store都存在了,按照我另一篇原理分析內(nèi)的非視圖部分已基本完成.

接下來我們?cè)谔幚硪晥D部分,即Provider.在這里我個(gè)人習(xí)慣從外層往內(nèi)寫.先寫Provider外殼,并將整個(gè)APP包裹在內(nèi);

src文件夾內(nèi),新建Root.js文件,該文件內(nèi)實(shí)現(xiàn)Provider對(duì)視圖部分的包裹


import React, { Component } from 'react';

import { Provider } from 'react-redux';

import configureStore from './store/ConfigureStore';

import App from './container/App';// app的入口

const store = configureStore();

export default class Root extends Component {??

? ? render() {? ??

? ? ? ? return (

? ? ? ? ? ? <Provider store={store}>

? ? ? ? ? ? ? ? <App />

? ? ? ? ? ?</Provider>

? ? ? ? )?

? ? }

}

import App from './container/App';這里對(duì)應(yīng)的是 app的入口 寫到這里的時(shí)候,本文件還沒有實(shí)現(xiàn)

9).實(shí)現(xiàn)視圖的部分代碼

container文件夾內(nèi)新建App.js文件,作為整個(gè)app的入口;

此處使用了react-navigation用來管理頁(yè)面;


import React, { Component } from 'react';

import {

View,

Text,

} from 'react-native';

import { StackNavigator } from 'react-navigation';

import LoginPage from '../pages/LoginPage'

import MainPage from '../pages/MainPage'

const App = StackNavigator({

Login: { screen: LoginPage },

Main: { screen: MainPage},

});

export default App

10.實(shí)現(xiàn)頁(yè)面(注意此處有很關(guān)鍵的一步,需要在頁(yè)面內(nèi)實(shí)現(xiàn)組件和store的關(guān)聯(lián),之所以能夠?qū)崿F(xiàn)不同的組件關(guān)聯(lián)不同的state也是在這一步進(jìn)行的)

此處代碼量較多,只粘貼關(guān)鍵代碼


紅框部分:多reducer內(nèi)選擇不同的reducer

class LoginPage extends Component {?

?static navigationOptions = {? ? title: 'LoginPage',? };??

shouldComponentUpdate(nextProps, nextState) {? ??

// 登錄完成,切成功登錄? ?

?if (nextProps.status === '登陸成功' && nextProps.isSuccess) {? ? ??

this.props.navigation.dispatch(resetAction)? ? ?

?return false;? ?

?}? ??

return true;??

}?

?render() {? ??

const { login } = this.props;? ??

return(

/*...components*/

)?

?}

}

export default connect(

(state) => ({

status: state.loginIn.status,

isSuccess: state.loginIn.isSuccess,

user: state.loginIn.user,

}),

(dispatch) => ({

login: () => dispatch(loginAction.login()),

})

)(LoginPage)

11).請(qǐng)大家自行實(shí)現(xiàn)加減法部分的邏輯并將其關(guān)聯(lián)到對(duì)應(yīng)的頁(yè)面內(nèi).

1.設(shè)定時(shí)間的所有處理類別; type

2.事件預(yù)處理過程; action

3.事件處理過程; reducer

4.通過reducer統(tǒng)一入口導(dǎo)出供外部使用;

5.實(shí)現(xiàn)視圖pages并將其與邏輯部分綁定到一起;connect

可查閱demo代碼

希望本文對(duì)大家有所幫助

有問題歡迎大家留言評(píng)論,會(huì)盡快回復(fù)的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市球匕,隨后出現(xiàn)的幾起案子帖烘,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件历极,死亡現(xiàn)場(chǎng)離奇詭異衷佃,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)氏义,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門惯悠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人克婶,你說我怎么就攤上這事情萤。” “怎么了筋岛?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵睁宰,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我贪磺,道長(zhǎng)诅愚,這世上最難降的妖魔是什么劫映? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任刹前,我火速辦了婚禮,結(jié)果婚禮上祖今,老公的妹妹穿的比我還像新娘拣技。我一直安慰自己,他們只是感情好徐绑,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布莫辨。 她就那樣靜靜地躺著,像睡著了一般盘榨。 火紅的嫁衣襯著肌膚如雪蟆融。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天捷犹,我揣著相機(jī)與錄音冕末,去河邊找鬼。 笑死枪孩,一個(gè)胖子當(dāng)著我的面吹牛藻肄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嘹屯,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼州弟,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼低零!你這毒婦竟也來了拯杠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤雄妥,失蹤者是張志新(化名)和其女友劉穎依溯,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體枝秤,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拜隧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年洪添,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了雀费。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡忿峻,死狀恐怖辕羽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绰寞,我是刑警寧澤铣口,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站件缸,受9級(jí)特大地震影響叔遂,放射性物質(zhì)發(fā)生泄漏争剿。R本人自食惡果不足惜佑稠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一舌胶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧幔嫂,春花似錦、人聲如沸锰茉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)协屡。三九已至全谤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間认然,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工盈匾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留毕骡,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓葵孤,卻偏偏與公主長(zhǎng)得像尤仍,于是被迫代替她去往敵國(guó)和親狭姨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子苏遥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容