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. 冰蝎动态二进制加密WebShell特征分析

    概述 冰蝎一款新型加密网站管理客户端,在实际的渗透测试过程中有非常不错的效果,能绕过目前市场上的大部分WAF.探针设备.本文将通过在虚拟环境中使用冰蝎,通过wireshark抓取冰蝎通信流量,结合平时 ...

  2. Linux系统测试工具

    一.文件系统测试工具简介 1.LTP 参考网站:http://oss.sgi.com/projects/ltp/ LTP(Linux Test Project)是由SGI和IBM联合发起的项目,提供一 ...

  3. mysql 数据库函数入门

  4. MFC 状态栏的使用 CstatusBar

    你在源文件头文件声明一下 CStatusBar   zhuangtailan; 然后在窗口初始化添加以下代码 zhuangtailan.Create(this);//意思是在本窗口创建 UINT id ...

  5. WC2020 联训 #19 矩阵

    好不容易自己切一道题 链接 Description 在一个 \(n×(n+1)\) 的棋盘上放棋子, \(n\) 行中每行都恰好有两枚棋子,并且 \(n+1\) 列中每列都至多有两枚棋子,设 \(n= ...

  6. spring boot引入外部jar包

    两种方法: 一:使用project-properties-java build path-Libraries 此方法的问题时不能使用mav打包. 二:写到POM里 首先在新建libs文件夹(根目录或者 ...

  7. 将git本地仓库同步到远程仓库

    同步到远程仓库可以使用git bash 也可以使用tortoiseGit 1.使用git bash 在仓库的所在目录,点击右键选择“Git Bash Here”,启动git bash程序. 然后再gi ...

  8. BZOJ1258 三角形tri

    三角形tri 找规律神题-- 发现如果以4结尾,把4改成1.2.3输出就行了. 如果不以4结尾: 把结尾改成4输出即可,因为一定与三角形的中心相邻. 规律1:如果把串的末尾删去,那么会回到上一层. 如 ...

  9. HihoCoder第七周:完全背包问题

    1043 : 完全背包 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 且说之前的故事里,小Hi和小Ho费劲心思终于拿到了茫茫多的奖券!而现在,终于到了小Ho领取奖励的时 ...

  10. CGridCtrl只点击规定行中的按钮才弹出对话框

    在头文件中添加: afx_msg void OnClick(NMHDR* pNMHDR, LRESULT* pResult); 添加映射:ON_NOTIFY(NM_CLICK, IDC_CUSTOM1 ...