美文网首页ReactJavaScript 进阶营
React.js学习笔记(14) React-router-re

React.js学习笔记(14) React-router-re

作者: woow_wu7 | 来源:发表于2017-12-31 05:02 被阅读73次

    (一) react-router-redux中间件

    所需环境:
    
    (1) 用creact-react-app脚手架启一个new项目
    create-react-app new
    
    (2)安装redux
    cnpm install redux --save-dev
    
    (3)安装react-redux
    cnpm install react-redux --save-dev
    
    (4)安装redux-devtools
    cnpm install redux-devtools --save-dev
    
    (5)安装react-router-dom
    cnpm install react-router-dom --save-dev
    
    

    (1) 安装react-router-redux

    react-router-redux作用:可以把router中的location(url信息等)注入到redux中,用redux来统一管理

    
    cnpm install react-router-redux@next --save-dev
    
    
    
    
    一般会用到react-router-redux中的:
    
    ConnectedRouter , routerReducer , routerMiddleware , push 
    
    // 这里要注意,ConnectedRouter的首字母要大写 
    
    // 注意是安装( @next版本 )
    
    // 在两个地方会用到react-router-redux
    
    1. 在store.js   用到routerReducer,routerMiddleware
    2. 在index.js   用到ConnectedRouter
    
    

    (2) 安装 history 库

    history是一个JavaScript库,可让您轻松管理任何运行JavaScript的会话历史记录。用来管理历史堆栈,导航,确认导航以及在会话之间保持状态。

    
    cnpm install history --save-dev
    
    

    (2) 新建 history.js

    
    import createHistory from 'history/createBrowserHistory';
    
    export default createHistory();
    
    
    
    history.js在两个地方会用到:
    
    1.store.js 中
    
    2.入口文件js中 (index.js)
    
    

    (3) store.js

    
    import {createStore, combineReducers, applyMiddleware} from 'redux';
    import { routerReducer, routerMiddleware} from 'react-router-redux';
    import username from '../component/username/reducer';
    import history from  '../history/history';               // 上面的history.js
    import thunkMiddleware from 'redux-thunk';               // redux-thunk中间件用于dispatch一个函数
    
    const totalReducer = {
        username:username,
        router:routerReducer                                          // routerReducer        
    }
    
    export const store = createStore(                                 // 根据规则建立store
        combineReducers({                                             // combineReducers组合多个reducer
            ...totalReducer
        }),
        window.devToolsExtension ? window.devToolsExtension() : undefined, // devTools插件
        applyMiddleware(thunkMiddleware,routerMiddleware(history))     // routerMiddleware
    );
    
    
    export function injectAsyncReducer(name, reducer) {   // 异步注入reducer
        store.AsyncReducers = store.AsyncReducers || {};
        if (store.AsyncReducers[name]) {
            return ;
        }
        store.AsyncReducers[name] = reducer;
        store.replaceReducer(combineReducers({   // store的api中的replaceReducer(nextReducer)方法
            ...totalReducer,
            ... store.AsyncReducers
        }))
    }
    
    

    (4) index.js入口文件

    
    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';
    import registerServiceWorker from './registerServiceWorker';
    import {Provider} from 'react-redux';            //Provider的作用是保存store给子组件中的connect使用
    import RouterA from './router/router';
    // import {BrowserRouter} from 'react-router-dom';
    import {ConnectedRouter} from 'react-router-redux';        // 引入ConnectedRouter
    import history from './history/history';
    
    import {store} from './store/store';
    ReactDOM.render(
        <Provider store={store}>
            <ConnectedRouter history={history}>               // 使用ConnectedRouter 
                <App>
                    <RouterA/>                     // 路由组件,在App中用{this.props.children}引入
                </App>
            </ConnectedRouter>
        </Provider>
    , document.getElementById('root'));
    registerServiceWorker();
    
    
    redux截图







    (二) injectAsyncReducer函数 (名字是自己定义的)

    作用: 实时更新的reducer

    (1) replaceReducer(nextReducer)

    replaceReducer(nextReducer)是redux的api中的 store 的一个函数

    • 作用:替换 store 当前用来计算 state 的 reducer。
      这是一个高级 API。只有在你需要实现代码分隔,而且需要立即加载一些 reducer 的时候才可能会用到它。在实现 Redux 热加载机制的时候也可能会用到。
    • ( 我的理解是: 实时更新的reducer )
    • (redux中文文档)http://www.redux.org.cn/docs/api/Store.html#replaceReducer

    (2) injectAsyncReducer函数定义

    store.js中
    
    
    export function injectAsyncReducer(name, reducer) {     // name, reducer作为参数
        store.AsyncReducers = store.AsyncReducers || {};    // 存在赋值,不存在赋值空对象
        if (store.AsyncReducers[name]) {      // store中的AsyncReducers对象存在name属性,就返回
            return ;
        }
        store.AsyncReducers[name] = reducer;   // 不存在name属性,就赋值给name属性
        store.replaceReducer(combineReducers({  // 用replaceReducer函数获得时时更新的reducer
            ...totalReducer, 
            ... store.AsyncReducers  // 拿到AsyncReducers对象,给combineReducers
        }))
    }
    
    
    

    (2) injectAsyncReducer函数使用

    container.js中
    
    
    import React,{Component} from 'react';
    import Username from './username';
    import {bindActionCreators}  from 'redux';
    import * as actionTotal from './action';
    import {connect} from 'react-redux';
    
    import {injectAsyncReducer} from '../../store/store';                    // 引入
    injectAsyncReducer('address',require('./reducer').default);              // 使用
    
    class usernameContainer extends Component {
        render() {
            return (
                <div>
                    <Username {...this.props}></Username>
                </div>
            )
        }
    }
    function mapStateToProps(state) {
        return {
            name: state.username.username
        }
    }
    function mapDispatchToProps(dispatch) {
        return bindActionCreators(actionTotal,dispatch)
    }
    export default connect(mapStateToProps,mapDispatchToProps)(usernameContainer)
    
    
    injectAsyncReducer函数效果图







    (三) redux-thunk中间件

    作用: dispatch一个函数

    • redux-thunk 支持 dispatch function,以此让 action creator 控制反转。被 dispatch 的 function 会接收 dispatch 作为参数,并且可以异步调用它。这类的 function 就称为 thunk。

    (1) 安装

    cnpm install redux-thunk --save-dev
    

    (2) 引入

    
    
    import {createStore, combineReducers, applyMiddleware} from 'redux';
    import username from '../component/username/reducer';
    import { routerReducer, routerMiddleware} from 'react-router-redux';
    import history from  '../history/history';
    import thunkMiddleware from 'redux-thunk';                                  // 引入
    
    const totalReducer = {
        username:username,
        router:routerReducer
    }
    
    export const store = createStore(
        combineReducers({
            ...totalReducer
        }),
        window.devToolsExtension ? window.devToolsExtension() : undefined,
        applyMiddleware(thunkMiddleware,routerMiddleware(history))             // 使用
    );
    
    
    
    

    (3) 使用

    action.js
    
    
    
    export function getImage() {
        return dispatch => {      // return 一个函数,dispatch函数作为参数
            const p = fetch('http://image.baidu.com/channel/listjson?pn=0&rn=30&tag1=%E7%BE%8E%E5%A5%B3&tag2=%E5%85%A8%E9%83%A8&ie=utf8',{
                method:'GET'
            }).then(result => result.json() );
    
            p.then(result => {
                console.log(result,'result');
                dispatch({      // dispatch一个action
                    type: actionTypes.GET_IMAGE,
                    payload: result
                })
            })
            
            return p;
        }
    }
    
    
    
    
    ------------------------------------------------------------------------------------
    reducer.js
    
    
    import actionTypes from './constant';
    
    const initialState = {
        username:{
            username: '重庆'
        },
        image:{}
    }
    
    
    export default function reducerA(state=initialState,action) {
        switch(action.type) {
            case actionTypes.GET_IMAGE:
                return {
                    ...state,
                    image:action.payload
                }    
            default:
                return state;
        }
    
    }
    
    
    
    
    ------------------------------------------------------------------------------------
    container.js
    
    
    
    import React,{Component} from 'react';
    import Username from './username';
    import {bindActionCreators}  from 'redux';
    import * as actionTotal from './action';
    import {connect} from 'react-redux';
    
    import {injectAsyncReducer} from '../../store/store';
    injectAsyncReducer('address',require('./reducer').default);
    
    class usernameContainer extends Component {
        render() {
            return (
                <div>
                    <Username {...this.props}></Username>
                </div>
            )
        }
    }
    function mapStateToProps(state) {
        return {
            name: state.username.username,
            imageUrl:state.address.image.dat
    
            // 拿到state.address.image.data命名为imageUrl,传给username.js
        }
    }
    function mapDispatchToProps(dispatch) {
        return bindActionCreators(actionTotal,dispatch)
    }
    export default connect(mapStateToProps,mapDispatchToProps)(usernameContainer)
    
    
    
    
    
    ------------------------------------------------------------------------------------
    username.js
    
    
    
    import React,{Component} from 'react';
    
    export default class username extends Component {
        getI = () => {
            this.props.getImage();
        }
        goG = (item,key) => {
            return (
                <div key={key}>
                    <img src={item.image_url} alt=""/> 
                </div>
            )
        }
        render() {
            // console.log(this.props.imageUrl,'this.props.imageUrl');
            return (
                <div>
                   主页
                    <div onClick={this.getI}>
                        点击获得图片
                    </div>
                    <br/>
                    <br/>
                    {
                         this.props.imageUrl && this.props.imageUrl.map(this.goG)
                    }
                </div>
            )
        }
    }
    
    
    redux.thunk效果图
    参考文档:
    (1) react-router-redux
    https://github.com/ReactTraining/react-router/tree/master/packages/react-router-redux
    (2)react-router v4 使用 history 控制路由跳转
    https://segmentfault.com/a/1190000011137828
    (3) redux-thunk
    https://github.com/gaearon/redux-thunk

    相关文章

      网友评论

        本文标题:React.js学习笔记(14) React-router-re

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