首页 文章

如何用redux和react-router组织状态?

提问于
浏览
14

Redux主张使用单一商店的单一商店 . 但是,使用react-router,您可以获得多个页面,每个页面都有自己的顶级根组件 .

应该如何使用具有多个页面的react-router应用程序连接redux? React-router 1.0不再允许您将props传递给路由,因此使路由器成为包含所有页面状态的顶级组件不再可行,也不可行 .

2 回答

  • 9

    如果您正在使用redux react-router,我强烈建议您使用redux-router - 这将允许您在商店中保留路由信息 - 我通常会进行以下设置 .

    redux-router: ^1.0.0-beta3 / react-router": ^1.0.0-rc1 / redux: "^3.0.2 / react: "^0.14.0

    //index.js [切入点]

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { Router, Route } from 'react-router';
    import { Provider } from 'react-redux';
    import createStore from './utils/create-store';
    import routes from './bootstrap/routes';
    import { ReduxRouter } from 'redux-router';
    
    const store = createStore(routes);
    
    ReactDOM.render(
        <Provider store={store}>
            <ReduxRouter>
                {routes}
            </ReduxRouter>
        </Provider>,
        document.getElementById('root')
    );
    

    // create-store.js

    import { applyMiddleware, createStore, combineReducers, compose } from 'redux';
    import * as reducers from '../reducers/index';
    import promiseMiddleware from './promise-middleware';
    import { routerStateReducer, reduxReactRouter } from 'redux-router';
    import history from './history'
    
    /**
     * Sets up the redux store.  Responsible for loading up the reducers and middleware.
     *
     * @param routes
     */
    export default function create(routes) {
        const composedReducers = combineReducers({
            router: routerStateReducer,
            ...reducers
        });
        const finalCreateStore = compose(applyMiddleware(promiseMiddleware),
            reduxReactRouter({
                routes,
                history
            }))(createStore);
        let store = finalCreateStore(composedReducers);
        return store;
    }
    

    // routes.js

    import React from 'react';
    import { Route } from 'react-router';
    import  App from './app';
    
    module.exports = (
        <Route component={App}>
            ...all your routes go here
        </Route>
    );
    

    // app.js

    import React, { PropTypes } from 'react';
    import { connect } from 'react-redux';
    
    export default class App extends React.Component {
    
        render() {
            const { props: { children } } = this;
            return (
                <div className="app-container">
                  {children}
                </div>
            );
        }
    }
    

    So as you can see there is one higher order component that wraps the rest of your routes

  • 3

    Redux-router is no longer compatible with react-router v4, and the above solution will not work.

    因此,我建议使用redux-little-router . 与redux-router不同,它不依赖于react-router,而是替代它 .

    有了它,你可以做以下事情:

    从异步操作推送到新路由:

    export function navigateAbout() {
      return (dispatch) => {
        dispatch(push('/about'))
      }
    }
    

    在redux-dev-tools中查看您的路由器详细信息(当前路径,查询字符串和参数),并像访问任何其他道具一样从您的商店访问这些详细信息:

    function mapStateToProps(state) {
      return {
        string: state.router.query.string
      }
    }
    

    PS . 您可以参考或使用已经实现的redux-little-redux的this react boilerplate

相关问题