Redux 入門

1.什麼是Redux

管理Web應用全局狀態的框架。前端

單頁面應用,顧名思義,和傳統項目的最明顯區別就是項目只有一個頁面,頁面有一個根元素,咱們寫的每個頁面是一個大的組件,前端接管路由來渲染不一樣的頁面組件。react

隨着應用的複雜,前端須要存儲更多的state,包括緩存的全局數據,本地生成還沒有持久化到服務器的數據,也包括 UI 狀態,如激活的路由,被選中的標籤,是否顯示加載動效或者分頁器等等。編程

若是是單純的數據緩存 也沒什麼須要考慮的東西,放到內存就能夠了, 重點是還要讓state和view有綁定的關係。state的變化可以觸發view的變化。redux

在咱們的項目中,沒有用redux以前,咱們都是頁面組件管理state,出現如下需求的時候,寫起來就比較複雜react-native

  • 某個組件的狀態,須要共享
  • 某個狀態須要在任何地方均可以拿到
  • 一個組件須要改變全局狀態
  • 一個組件須要改變另外一個組件的狀態

2.Redux的原則和設計思想

2.1 三大原則

  • 單一數據源:整個應用的 state 被儲存在一棵 object tree 中,而且這個 object tree 只存在於惟一一個 store 中
  • State 是隻讀的:唯一改變 state 的方法就是觸發 action,action 是一個用於描述已發生事件的普通對象。
  • 使用純函數來執行修改: 爲了描述 action 如何改變 state tree ,你須要編寫 reducers。只要是一樣的輸入,一定獲得一樣的輸出。

純函數是函數式編程的概念,必須遵照如下一些約束。
不得改寫參數
不能調用系統 I/O 的API
不能調用Date.now()或者Math.random()等不純的方法,由於每次會獲得不同的結果api

2.2 設計思想:

(1)Web 應用是一個狀態機,視圖與狀態是一一對應的。緩存

(2)全部的狀態,保存在一個對象裏面。服務器

3.Redux中的概念

3.1 Action

執行的動做,包括動做所須要的數據,改變store數據的惟一來源,通常是經過store.dispatch() 將 action 傳到 store。微信

Action 本質上是 JavaScript 普通對象。框架

flux-standard-action FSA標準

  • type,必須,string或者Symbol
  • payload,可選,執行action所須要的數據,任何類型
  • error,可選,標識這個action是否有錯誤,true or false
  • meta,可選,任何類型,payload以外的其餘數據。

3.2 Reducer

根據action 作更新state的操做。

Action 只是描述了有事情發生了這一事實,並無指明應用如何更新 state。而這正是 reducer 要作的事情。

3.3 Store

Store就是保存全局state的容器,保存三個經常使用的api

  • getState,獲取當前的state
  • subscribe,給store變化添加監聽函數
  • dispatch,用於接受action的方法,觸發reducer和監聽函數

3.4 單項數據流

用戶經過View,dispatch 相應的action,store調用reducer獲取最新的state,並觸發經過subscribe訂閱的監聽函數,監聽函數中咱們經過store的getState方法獲取最新的state,更新view。
工做流程圖
image description)

4.應用實例

simpleredux/index.js

import {createStore} from 'redux';
 
export function createAction(type, payload) {
    return {
        type,
        payload
    }
}
const initialState = {
    time: new Date().getTime()
}
 
function reducer(state = initialState, action) {
    switch (action.type) {
        case 'NOW_TIME':
            return {
                ...state,
                time: action.payload
            }
        default:
            return state;
    }
}
 
let store;
export function getStore() {
    if(store) return store;
    return store = createStore(reducer);
}

TestRedux.js

'use strict';
 
import React, { Component } from 'react';
 
import {
    StyleSheet,
    View,
    Text
} from 'react-native';
import MtButton from '@scfe/react-native-button';
import {getStore, createAction} from '../../simpleredux/index';
const store = getStore();
class TestRedux extends Component {
    constructor(props) {
        super(props);
        let state = store.getState();
        this.state = {
            time: state.time
        };
        store.subscribe(()=>{
            let state = store.getState();
            this.setState({
                time: state.time
            });
        });
    }
 
    _sendAction() {
        let action = createAction('NOW_TIME', new Date().getTime());
        store.dispatch(action);
    }
    render() {
        return (
            <View style={styles.container}>
                <Text>{this.state.time}
                </Text>
                <MtButton text="發出action" onPress={this._sendAction.bind(this)} />
            </View>
        );
    }
}
 
const styles = StyleSheet.create({
    container: {
        flex: 1,
        padding: 40
    }
});
 
export default TestRedux;

若是以爲有收穫請關注微信公衆號 前端良文 每週都會分享前端開發中的乾貨知識點。

相關文章
相關標籤/搜索