13.React中使用Redux數(shù)據(jù)流

1.Redux概述


當頁面渲染完成后,UI就已經(jīng)出現(xiàn),用戶觸發(fā)了UI上的一些action,action將被送到一個叫Reducer的方法里面去,Reducer將會更新Store,Store中包含state。
使用場景:
組件之間共享信息,例如,用戶登錄之后客戶端會存儲用戶信息(如userid、頭像等),而系統(tǒng)的很多個組件都會用到這些信息,例如收藏、點贊、評論等。因此每個系統(tǒng)都需要一個管理多組間使用的公共信息的功能,這就是Redux的作用。

2.安裝

npm install react-redux redux


網(wǎng)站:
http://redux.js.org/
http://cn.redux.js.org/

3.Redux和React集成

  • 第一步:創(chuàng)建更新用戶信息的Action
    我們現(xiàn)在主要做的就是初始化城市信息。
    首先判斷l(xiāng)ocalStorage中有沒有城市信息,如果有,那么我們就要更新redux中的userinfo中的cityname。
    這里的action就是一個改變redux存儲內(nèi)容的行為,這里更新redux中的userinfo中的cityname就是我們的action


//這是redux觸發(fā)數(shù)據(jù)改變的行為,type類型要和reducer中定義的actiontype相同
//第一步:創(chuàng)建更新用戶信息的Action
export function update(data) {
    return {
        type:'USERINFO_UPDATE',
        data
    }
}
  • 第二步:根據(jù)action定義計算規(guī)則,即reducer



    rootReducer.js是所有規(guī)則的入口,可以在這里繼續(xù)添加其他規(guī)則

import {combineReducers} from 'redux'
import userinfo from './userinfo'
//這是redux的第一步定義規(guī)則,這是所有規(guī)則的入口,可以存放多個規(guī)則。
const rootReducer=combineReducers({
    userinfo:userinfo
});

export default rootReducer;

userinfo.js是我們定義的一個和用戶相關的規(guī)則,內(nèi)容如下:
這里的action就是第一步創(chuàng)建的action,通過action.type來匹配action和reducer

const initialState ={};
//這是和用戶信息相關的規(guī)則,這里定義了一個更新城市名字的規(guī)則
export default function userinfo(state=initialState,action) {
    switch (action.type){
        //修改城市名字
        case 'UPDATE_CITYNAME':
            return action.data;

        default:
            return state;

    }
}
  • 第三步:根據(jù)reducer創(chuàng)建store


import {createStore} from 'redux'
import rootReducer from '../reducer/rootReducer'

//redux第二步,創(chuàng)建store
export default function configureStore(initialState) {

        const store = createStore(rootReducer, initialState,
            // 觸發(fā) redux-devtools
            window.devToolsExtension ? window.devToolsExtension() : undefined
        );
        return store;

}

第四步:監(jiān)聽數(shù)據(jù)變化
在ReactDom.render的index.jsx頁面上,為自己的入口組件添加外層<provider></provider>標簽。

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import RouterMap from './routerMap';
import registerServiceWorker from './registerServiceWorker';
import {Provider} from 'react-redux'
import configureStore from './store/configStore'
const store=configureStore();
ReactDOM.render(
    <Provider store={store}>
        <RouterMap/>
    </Provider>
    ,
    document.getElementById('root'));

registerServiceWorker();

第五步:為App組件綁定redux react,根據(jù)路由規(guī)則所有的組件都是App的子組件。所以每次都會先進入App組件
我們在App組件中給Redux初始設置用戶信息,然后在其他組件中獲得Redux中的用戶信息。

  • App組件
import React from 'react';

import './App.css';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import * as userInfoActions from './action/userInfoActions'

class App extends React.Component {
    constructor() {
        super();
        this.state = {initDone: false};
    }

    componentDidMount() {
        // 獲取位置信息
        let cityName = localStorage.cityName;
        if (cityName == null) {
            cityName = '北京';
        }
        //觸發(fā)redux的修改行為
        this.props.userInfoActions.update({
            cityName: cityName
        });

        // 更改狀態(tài)
        this.setState({
            initDone: true
        })
    }


//首先判斷是否完成初始化
    render(){
        return (
            <div>
                {
                    this.state.initDone ? this.props.children : <div>正在加載</div>
                }

            </div>
        );
    }
}



//-------------------redux react 綁定--------------------

//當前組件如需使用redux中的共享數(shù)據(jù),在此設置,就能夠當作屬性來使用
function mapStateToProps(state) {
    return {}
}

//觸發(fā)數(shù)據(jù)改變
function mapDispatchToProps(dispatch) {
    return {
        userInfoActions: bindActionCreators(userInfoActions, dispatch),
    }
}

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(App)

  • 在Home組件中應用這些信息
import React from 'react';
import HomeHeader from '../component/home/homeheader/HomeHeader';
import Category from '../component/home/category/Category';
import Recomment from '../component/home/recommend/Recomment';
import Likelist from '../component/home/likelist/LikeList';
import { connect } from 'react-redux';
class Home extends React.Component{
    render(){
        return(
            <div>
                <HomeHeader cityName={this.props.userinfo.cityName}/>
                <Category/>
                <Recomment/>
                <Likelist cityName={this.props.userinfo.cityName}/>
            </div>
        );
    }
}

// -------------------redux react 綁定--------------------

function mapStateToProps(state) {
    return {
        userinfo: state.userinfo
    }
}

//觸發(fā)數(shù)據(jù)變化
function mapDispatchToProps(dispatch) {
    return {
    }
}
export default connect(
    mapStateToProps,
    mapDispatchToProps
)(Home)

4.異步react-thunk插件的使用

我們希望在頁面初始化的階段,從后臺根據(jù)用戶的username,返回該用戶所有的收藏商品id,并存儲到redux中。

  • 首先定義這個action


//更新收藏列表
export function update(data) {
    return {
        type:'STORE_UPDATE',
        data
    }
}
//在App.js中完成頁初始化,從后臺獲取該用戶的所有收藏商品id存儲到redux中
//這里先fetch從后臺獲取json,然后觸發(fā)將json更新到redux的update方法。
export function getInitStore(username) {
    return function (dispatch){
        console.log('getInitStore執(zhí)行了');
        let option={method:'GET'};
        fetch(`/api/store/getStore/${username}`,option)
            .then(res => res.json())
            .then(json => dispatch(update(json)));
    };
}
  • 之后根據(jù)action定義規(guī)則reducer


const initialState =[];
//收藏創(chuàng)建的規(guī)則
export default function store(state=initialState,action) {
    switch (action.type){
        //
        case 'STORE_UPDATE':
            return action.data;

        default:
            return state;

    }
}

在rootReducer中添加規(guī)則store

import {combineReducers} from 'redux'
import userinfo from './userinfo'
import store from './store'
//這是redux的第一步定義規(guī)則,這是所有規(guī)則的入口,可以存放多個規(guī)則。
const rootReducer=combineReducers({
    userinfo:userinfo,
    store:store
});

export default rootReducer;
  • 根據(jù)reducer創(chuàng)建redux的存儲區(qū)



    需要安裝redux-thunk插件

npm install redux-thunk --save
import thunkMiddleware from 'redux-thunk';
import {createStore,applyMiddleware,compose} from 'redux'
import rootReducer from '../reducer/rootReducer'

//創(chuàng)建store
export default function configureStore(initialState) {
    const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
    const store = createStore(rootReducer,initialState,
        composeEnhancers(applyMiddleware(thunkMiddleware)
        ));

    return store;

}
  • 監(jiān)聽數(shù)據(jù)變化(參考3中第四步)
    在ReactDom.render的index.jsx頁面上,為自己的入口組件添加外層<provider></provider>標簽。
  • 在app.js中獲得redux的初始值
import React from 'react';

import './App.css';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import * as userInfoActions from './action/userInfoActions'
import * as storeActions from './action/storeActions';

class App extends React.Component {
    constructor() {
        super();
        this.state = {initDone: false};
    }

    componentDidMount() {
        // 獲取位置信息
        let cityName = localStorage.cityName;
        if (cityName == null) {
            cityName = '北京';
        }
        //觸發(fā)redux的修改行為
        this.props.userinfo.cityName=cityName;
        this.props.userInfoActions.update(this.props.userinfo);

        //獲取用戶名
        let username=localStorage.username;
        if(username!=null){
            //觸發(fā)redux的修改行為
            this.props.userinfo.username=username;
            this.props.userInfoActions.update(this.props.userinfo);

            //觸發(fā)從后臺根據(jù)username獲取個人收藏商品id,存儲在redux中
            if(this.props.userinfo.username!=null)
                //從后臺獲取收藏信息,觸發(fā)action
                this.props.storeActions.getInitStore(this.props.userinfo.username)
        }

        // 更改狀態(tài)
        this.setState({
            initDone: true
        })
    }


//首先判斷是否完成初始化
    render(){
        return (
            <div>
                {
                    this.state.initDone ? this.props.children : <div>正在加載</div>
                }

            </div>
        );
    }
}



//-------------------redux react 綁定--------------------

//當前組件如需使用redux中的共享數(shù)據(jù),在此設置,就能夠當作屬性來使用
function mapStateToProps(state) {
    return {
        userinfo: state.userinfo,
        store:state.store
    }
}

//觸發(fā)數(shù)據(jù)改變
function mapDispatchToProps(dispatch) {
    return {
        userInfoActions: bindActionCreators(userInfoActions, dispatch),
        storeActions: bindActionCreators(storeActions, dispatch)
    }
}

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(App)

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容