記錄一篇redux-saga的基本使用過程

安裝

npm install --save redux
npm install --save redux-saga

配置action

actionType

建立文件src/actions/types.js,在types.js文件中添加須要的action類型react

export const TEST1_ACTION = 'test1';
export const SET_TEST2_ACTION = 'change_test2';
export const SET_TEST3_ACTION = 'change_test3';

createActions

建立文件src/actions/test.js,在test.js文件中編寫actionios

import {TEST1_ACTION, SET_TEST2_ACTION, SET_TEST3_ACTION} from './types

// 獲取test1的值
export const getTest1Action = () => {
    return {
        type:TEST1_ACTION
    }
}

// 寫入test2的值
export const setTest2Action = (testValue) => {
    return {
        type:SET_TEST2_ACTION,
        payload:testValue
    }
}

// 寫入test3的值
export const setTest3Action = (payload) => {
    return {
        type:SET_TEST3_ACTION,
        payload
    }
}

配置reducer

由於一個項目中可能會有不少地方須要用到reducer,因此把這些reducer文件分開管理比較好,好比:test.js,settings.js,auth.js等等。npm

建立文件src/reducers/test.js,編寫test reducerredux

import {TEST1_ACTION, SET_TEST2_ACTION, SET_TEST3_ACTION} from '../actions/types

// 初始化
const initTest = {
    test1:'這是test1初始化的值',
    test2:'這是test2初始化的值',
    test3:'這是test3初始化的值'
}

export default (state = initTest, action) =>{
    switch (action.type) {
        case TEST1_ACTION:{
            return {
                ...state
            }
        }
        case SET_TEST2_ACTION:{
            return {
                ...state,
                test2:action.payload
            }
        }
        case SET_TEST3_ACTION:{
            return {
                ...state,
                test3:action.payload.testValue
            }
        }
        default:
        return state
    }
}

建立文件src/reducers/index.jsaxios

import {combineReducers} from 'redux'
import test from './test'


const reducers = combineReducers({
    test,
    /*
    還能夠繼續加入其它的reducer文件,好比:
    settings,
    auth,
    */
});

export default reducers;

配置saga

建立文件src/sagas/test.jsapi

import {all,fork,put,takeEvery} from 'redux-saga/effects'
import {setTest2Action, setTest3Action} from "../actions/test"
import {SET_TEST2_ACTION, SET_TEST3_ACTION} from "../actions/actionTypes"
import axios from 'axios'

function* changeTest2 (testValue) {
    yield put(setTest2Action(testValue))
}

function* changeTest3 (obj) {
    try{
        // 這裏使用axios從網絡獲取數據演示,沒有安裝axios的須要先安裝它。
        // 期間響應狀態碼判斷就省略了,就當它每次請求都成功得到testValue的數據
        response = axios.get('http://localhost/api/test')
        
        // 假設response.data裏面有一個key爲testValue的值
        yield put(setTest3Action(response.data))
    } catch (error) {
        console.error('這裏也能夠yield put一個createAction,這裏不做演示')
    }
}

export function* setTest2 () {
    yield takeEvery(SET_TEST2_ACTION, changeTest2)
}

export function* setTest3 () {
    yield takeEvery(SET_TEST3_ACTION, changeTest3)
}

export default function* testSaga(){
    yield all([
        fork(setTest2),
        fork(setTest3),
    ])
}

建立文件src/sagas/index.js數組

import {all} from 'redux-saga/effects';
import testSaga from './test'

export default function* rootSaga() {
    yield all([
        testSaga()
    ]);
}

配置store

import {applyMiddleware, compose, createStore} from 'redux';
import reducers from '../reducers/index';
import createSagaMiddleware from 'redux-saga';
import rootSaga from '../sagas/index';


const sagaMiddleware = createSagaMiddleware();

// 使用數組是爲了方便之後繼續添加中間件
const middlewares = [sagaMiddleware];

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
  reducers,
  composeEnhancers(applyMiddleware(...middlewares))
);

sagaMiddleware.run(rootSaga);

export default store;

App入口文件路由配置

import React from 'react'
import {Provider} from 'react-redux'
import store from './store'
import Test from './Test/'
import {BrowserRouter, Route, Switch} from "react-router-dom"

const MainApp = () =>
  <Provider store={store}>
    <BrowserRouter>
      <Switch>
        <Route path="/" component={Test}/>
      </Switch>
    </BrowserRouter>
  </Provider>;

export default MainApp

Test.js

src/Test/index.js網絡

import React from 'react'
import {connect} from 'react-redux'
import {setTest2Action, setTest3Action} from '../actions/test'

class Test extends React.Component {
    render() {

        const {test1, test2, test3, setTest2Action, setTest3Action} = this.props

        return {
            <div>
                <div>
                    test1的值爲:{test1}
                </div>
                <div>
                    test2的值爲:{test2}
                    <button onClick={setTest2Action('abc')}>設置test2的值爲 abc</button>
                </div>
                <div>
                    test3的值爲:{test3}
                    <button onClick={setTest3Action()}>從網絡獲取test3的值</button>
                </div>
            </div>
        }
    }
}

const mapStateToProps = ({test}) => {
    const {test1,test2,test3} = test;
    return {test1,test2,test3}
}

export default connect (mapStateToProps,{setTest2Action, setTest3Action})(Test)

至此,便可運行 npm start進行測試了react-router

相關文章
相關標籤/搜索