美文网首页
13.React中使用Redux数据流

13.React中使用Redux数据流

作者: Ching_Lee | 来源:发表于2018-02-26 14:15 被阅读0次

    1.Redux概述


    当页面渲染完成后,UI就已经出现,用户触发了UI上的一些action,action将被送到一个叫Reducer的方法里面去,Reducer将会更新Store,Store中包含state。
    使用场景:
    组件之间共享信息,例如,用户登录之后客户端会存储用户信息(如userid、头像等),而系统的很多个组件都会用到这些信息,例如收藏、点赞、评论等。因此每个系统都需要一个管理多组间使用的公共信息的功能,这就是Redux的作用。

    2.安装

    npm install react-redux redux
    

    网站:
    http://redux.js.org/
    http://cn.redux.js.org/

    3.Redux和React集成

    • 第一步:创建更新用户信息的Action
      我们现在主要做的就是初始化城市信息。
      首先判断localStorage中有没有城市信息,如果有,那么我们就要更新redux中的userinfo中的cityname。
      这里的action就是一个改变redux存储内容的行为,这里更新redux中的userinfo中的cityname就是我们的action


    //这是redux触发数据改变的行为,type类型要和reducer中定义的actiontype相同
    //第一步:创建更新用户信息的Action
    export function update(data) {
        return {
            type:'USERINFO_UPDATE',
            data
        }
    }
    
    • 第二步:根据action定义计算规则,即reducer



      rootReducer.js是所有规则的入口,可以在这里继续添加其他规则

    import {combineReducers} from 'redux'
    import userinfo from './userinfo'
    //这是redux的第一步定义规则,这是所有规则的入口,可以存放多个规则。
    const rootReducer=combineReducers({
        userinfo:userinfo
    });
    
    export default rootReducer;
    

    userinfo.js是我们定义的一个和用户相关的规则,内容如下:
    这里的action就是第一步创建的action,通过action.type来匹配action和reducer

    const initialState ={};
    //这是和用户信息相关的规则,这里定义了一个更新城市名字的规则
    export default function userinfo(state=initialState,action) {
        switch (action.type){
            //修改城市名字
            case 'UPDATE_CITYNAME':
                return action.data;
    
            default:
                return state;
    
        }
    }
    
    • 第三步:根据reducer创建store


    import {createStore} from 'redux'
    import rootReducer from '../reducer/rootReducer'
    
    //redux第二步,创建store
    export default function configureStore(initialState) {
    
            const store = createStore(rootReducer, initialState,
                // 触发 redux-devtools
                window.devToolsExtension ? window.devToolsExtension() : undefined
            );
            return store;
    
    }
    

    第四步:监听数据变化
    在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,根据路由规则所有的组件都是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 = '北京';
            }
            //触发redux的修改行为
            this.props.userInfoActions.update({
                cityName: cityName
            });
    
            // 更改状态
            this.setState({
                initDone: true
            })
        }
    
    
    //首先判断是否完成初始化
        render(){
            return (
                <div>
                    {
                        this.state.initDone ? this.props.children : <div>正在加载</div>
                    }
    
                </div>
            );
        }
    }
    
    
    
    //-------------------redux react 绑定--------------------
    
    //当前组件如需使用redux中的共享数据,在此设置,就能够当作属性来使用
    function mapStateToProps(state) {
        return {}
    }
    
    //触发数据改变
    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
        }
    }
    
    //触发数据变化
    function mapDispatchToProps(dispatch) {
        return {
        }
    }
    export default connect(
        mapStateToProps,
        mapDispatchToProps
    )(Home)
    
    

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

    我们希望在页面初始化的阶段,从后台根据用户的username,返回该用户所有的收藏商品id,并存储到redux中。

    • 首先定义这个action


    //更新收藏列表
    export function update(data) {
        return {
            type:'STORE_UPDATE',
            data
        }
    }
    //在App.js中完成页初始化,从后台获取该用户的所有收藏商品id存储到redux中
    //这里先fetch从后台获取json,然后触发将json更新到redux的update方法。
    export function getInitStore(username) {
        return function (dispatch){
            console.log('getInitStore执行了');
            let option={method:'GET'};
            fetch(`/api/store/getStore/${username}`,option)
                .then(res => res.json())
                .then(json => dispatch(update(json)));
        };
    }
    
    • 之后根据action定义规则reducer


    const initialState =[];
    //收藏创建的规则
    export default function store(state=initialState,action) {
        switch (action.type){
            //
            case 'STORE_UPDATE':
                return action.data;
    
            default:
                return state;
    
        }
    }
    

    在rootReducer中添加规则store

    import {combineReducers} from 'redux'
    import userinfo from './userinfo'
    import store from './store'
    //这是redux的第一步定义规则,这是所有规则的入口,可以存放多个规则。
    const rootReducer=combineReducers({
        userinfo:userinfo,
        store:store
    });
    
    export default rootReducer;
    
    • 根据reducer创建redux的存储区



      需要安装redux-thunk插件

    npm install redux-thunk --save
    
    import thunkMiddleware from 'redux-thunk';
    import {createStore,applyMiddleware,compose} from 'redux'
    import rootReducer from '../reducer/rootReducer'
    
    //创建store
    export default function configureStore(initialState) {
        const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
        const store = createStore(rootReducer,initialState,
            composeEnhancers(applyMiddleware(thunkMiddleware)
            ));
    
        return store;
    
    }
    
    • 监听数据变化(参考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 = '北京';
            }
            //触发redux的修改行为
            this.props.userinfo.cityName=cityName;
            this.props.userInfoActions.update(this.props.userinfo);
    
            //获取用户名
            let username=localStorage.username;
            if(username!=null){
                //触发redux的修改行为
                this.props.userinfo.username=username;
                this.props.userInfoActions.update(this.props.userinfo);
    
                //触发从后台根据username获取个人收藏商品id,存储在redux中
                if(this.props.userinfo.username!=null)
                    //从后台获取收藏信息,触发action
                    this.props.storeActions.getInitStore(this.props.userinfo.username)
            }
    
            // 更改状态
            this.setState({
                initDone: true
            })
        }
    
    
    //首先判断是否完成初始化
        render(){
            return (
                <div>
                    {
                        this.state.initDone ? this.props.children : <div>正在加载</div>
                    }
    
                </div>
            );
        }
    }
    
    
    
    //-------------------redux react 绑定--------------------
    
    //当前组件如需使用redux中的共享数据,在此设置,就能够当作属性来使用
    function mapStateToProps(state) {
        return {
            userinfo: state.userinfo,
            store:state.store
        }
    }
    
    //触发数据改变
    function mapDispatchToProps(dispatch) {
        return {
            userInfoActions: bindActionCreators(userInfoActions, dispatch),
            storeActions: bindActionCreators(storeActions, dispatch)
        }
    }
    
    export default connect(
        mapStateToProps,
        mapDispatchToProps
    )(App)
    
    

    相关文章

      网友评论

          本文标题:13.React中使用Redux数据流

          本文链接:https://www.haomeiwen.com/subject/rxrexftx.html