connected-react-router是一个绑定react-router到redux的组件,来实现双向绑定router的数据到redux store中,这么做的好处就是让应用更Redux化,可以在action中实现对路由的操作。

这个组件的关键就在于使用了react-router中的一个关键组件,也就是ReactTraining/history,这个组件看了下文档,作者是这么解释的

The history library is a lightweight layer over browsers' built-in History and Location APIs. The goal is not to provide a full implementation of these APIs, but rather to make it easy for users to opt-in to different methods of navigation.

按照我的理解应该是对浏览器原本的history对象做了一定的增强,同时应该对ReactNative等环境做了一定的polyfill。

使用connected-react-router这个库的关键点就在于创建合适的history对象

我当前connected-react-router的版本为v6,需要react router大于v4,并且react-redux大于v6,react大于v16.4.0

先看index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux'
import configureStore, { history } from './configureStore'
import { ConnectedRouter } from 'connected-react-router'
import routes from './routes' const store = configureStore() ReactDOM.render(
<Provider store={store}>// Provider使用context将store传给子组件
<ConnectedRouter history={history}>//ConnectedRouter传递history对象作为props
{ routes }
</ConnectedRouter>
</Provider>
, document.getElementById('root'));

configureStore.js提供history与store

import { createBrowserHistory } from 'history'
import { applyMiddleware, compose, createStore } from 'redux'
import { routerMiddleware } from 'connected-react-router'
import createRootReducer from './reducers'
export const history = createBrowserHistory()
export default function configureStore(preloadedState) {
  const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || 
  compose
  
  const store = createStore(
    createRootReducer(history),
    preloadedState,
    composeEnhancer(
      applyMiddleware(
        routerMiddleware(history),
      ),
    ),
  )
  return store
}

使用createBrowserHistory()创建history。

const history = createBrowserHistory()

使用redux-devtools-extension

window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__

reducers/index.js

import { combineReducers } from 'redux'
import { connectRouter } from 'connected-react-router'
import counterReducer from './counter' const rootReducer = (history) => combineReducers({
count: counterReducer,
router: connectRouter(history)
}) export default rootReducer

combineReducers方法,用于 Reducer 的拆分。你只要定义各个子 Reducer 函数,然后用这个方法,将它们合成一个大的 Reducer

reducers/counter.js

const counterReducer = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
} export default counterReducer

routes/index.js

import React from 'react'
import { Route, Switch } from 'react-router'
import Counter from '../components/Counter'
import { Link } from 'react-router-dom'
const routes = (
  <div>
    <div>
        <Link to="/">Home</Link> 
        <Link to="/hello">Hello</Link> 
        <Link to="/counter">Counter</Link>
    </div>
    <Switch>
      <Route exact path="/" ><div>Home</div></Route>
      <Route path="/hello" ><div>Hello</div></Route>
      <Route path="/counter" component={Counter} />
      <Route ><div>No Match</div></Route>
    </Switch>
  </div>
)
export default routes

components/Counter.js

import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { increment, decrement } from '../actions/counter' const Counter = (props) => (
<div>
Counter: {props.count}
<button onClick={props.increment}>+</button>
<button onClick={props.decrement}>-</button>
</div>
) Counter.propTypes = {
count: PropTypes.number,
increment: PropTypes.func.isRequired,
decrement: PropTypes.func.isRequired,
} const mapStateToProps = state => ({
count: state.count,
}) const mapDispatchToProps = dispatch => ({
increment: () => dispatch(increment()),
decrement: () => dispatch(decrement()),
}) export default connect(mapStateToProps, mapDispatchToProps)(Counter)

actions/counter.js

export const increment = () => ({
type: 'INCREMENT',
}) export const decrement = () => ({
type: 'DECREMENT',
})

使用connected-react-router使router与store同步的更多相关文章

  1. [React] 10 - Tutorial: router

    Ref: REACT JS TUTORIAL #6 - React Router & Intro to Single Page Apps with React JS Ref: REACT JS ...

  2. vue & vue router & dynamic router

    vue & vue router & dynamic router https://router.vuejs.org/guide/essentials/dynamic-matching ...

  3. router.go,router.push,router.replace的区别

    除了使用 <router-link> 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现.当你点击 <router-link> 时,这个 ...

  4. [Angular2 Router] Programmatic Router Navigation via the Router API - Relative And Absolute Router Navigation

    In this tutorial we are going to learn how to navigate programmatically (or imperatively) by using t ...

  5. vue router.push(),router.replace(),router.go()和router.replace后需要返回两次的问题

    转载:https://www.cnblogs.com/lwwen/p/7245083.html https://blog.csdn.net/qq_15385627/article/details/83 ...

  6. vue router.push(),router.replace(),router.go()

    1.router.push(location)=====window.history.pushState 想要导航到不同的 URL,则使用 router.push 方法.这个方法会向 history ...

  7. [Angular2 Router] Index router

    Index router as default router. import {RouterModule} from "@angular/router"; import {NotF ...

  8. $router和router区别

    this.$router.push({path:'/'})//这个是js编程式的一种动态跳转路由方式,是全局的路由对象. 而写在router声明文件中的router是自己定义实例化的一个对象.可以使用 ...

  9. React中setState 什么时候是同步的,什么时候是异步的?

    class Example extends React.Component { constructor() { super(); this.state = { val: 0 }; } componen ...

随机推荐

  1. poj 2576 Tug of War

    还是神奇的随机算法,,(看视频说这是爬山法??) 其实就是把序列随机分成两半(我太弱,只知道random_shuffle),然后再每个序列里rand一个位置,x,y然后比较是不是交换之后是更优的. 然 ...

  2. Android实现三级联动下拉框下拉列表spinner

    原文出处:http://www.cnblogs.com/zjjne/archive/2013/10/03/3350107.html 主要实现办法:动态加载各级下拉值的适配器 在监听本级下拉框,当本级下 ...

  3. 接口补偿机制需求分析&方案设计

    接口补偿机制需求分析&方案设计文章目录接口补偿机制需求分析&方案设计需求分析背景解决方案业务示例注意事项示例业务Controller实现重试信息类&数据处理入库接口重试的主要方 ...

  4. NAND Flash驱动

    硬件原理及分析 管脚说明         Pin Name Pin Function R/B(RnB) The R/B output indicates the status of the devic ...

  5. 基于 Annotation 的装配(注解)

    注解:就是一个类,使用@注解名称 开发中:使用注解 取代 xml配置文件. 1. @Component取代<bean class=""> @Component(&quo ...

  6. linux下安装jdk&&Tomcat环境

    linux系统 Centos6 下部署应用服务 jdk-1.7 环境安装:(切换到root用户下操作)1. 在 /usr/local 目录下创建jdk7文件 mkdir /usr/local/jdk7 ...

  7. cf221 D. Little Elephant and Array

    题解真的是太神奇了2333 用离线和树状数组(为什么感觉和HH的项链是的,什么鬼),比较巧妙的是他把整个数列分成几段.用一个vector来记录每个数出现的位置.一共就是data[a[i]][sz]-- ...

  8. Python序列内单双引的问题——未解决

    在学习python基础的时候,遇到这样一个问题: tuple=(2,2.3,"yeah",5.6,False)list=[True,5,"smile"] 这样输 ...

  9. linux下操作oracle

    ps -ef|grep ora #查看oracle状态 lsnrctl status #查看监听的状态 lsnrctl start |stop |reload #启动|停止|重启 监听 登录oracl ...

  10. enlipse 快捷键

    ctrl+shift+o  去掉多余的引用类