react-router + redux + react-redux 的例子与分析
一个 react-router + redux + react-redux 的例子与分析
index.js
import React from 'react'
import ReactDom from 'react-dom'
import App from './App'
ReactDom.render(
<App/>,
document.getElementById('root')
)
没什么好说的
App.js :
import React from 'react'
import { createStore, applyMiddleware } from 'redux'
import { Provider } from 'react-redux'
import thunk from 'redux-thunk'
import reducers from './reducers'
import RouterMap from './router'
let store = createStore(reducers, applyMiddleware(thunk))
const App = () => {
return (
<Provider store={ store }>
<RouterMap/>
</Provider>
)
}
export default App
代码分析:
- reducers: redux 中的 reducers
- thunk: 异步action 的插件
- applyMiddleware: react 的中间件,用于添加插件
- RouterMap: 路由配置
- Provider:让所有容器组件都可以访问 store
- createStore: redux 生成 store 的方法
例子中的:RouterMap
import React from 'react'
// react-router 相关
import { Router, Route, Switch } from 'react-router-dom'
// 浏览器的History模式
import createHistory from 'history/createBrowserHistory'
// 生成一个redux容器的方法
import { connect } from 'react-redux'
// 一个action
import { initCity } from '../actions/userinfo'
// 组件
import Home from '../containers/Home'
import City from '../containers/City'
// 创建 history
const history = createHistory()
class App extends React.Component {
render() {
return (
<Router history={ history }>
<Switch>
<Route exact path="/" component={ Home }></Route>
<Route path="/city" component={ City }></Route>
</Switch>
</Router>
)
}
componentDidMount() {
this.props.initCity(cityName)
}
}
function mapStateToProps(state) {
return {
userInfo: state.userInfo
}
}
function mapDispatchToProps(dispatch, ownprops) {
return {
initCity: (cityName) => {
}
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(App)
代码分析:
- connect:
- 该方法接受2个参数,返回一个函数,返回的函数的参数通常 是react 组件,例子是App
- 参数1是函数,函数接收 store 中的 state 作为参数,通常 返回 state 中的数据,例子中的App组件可以通过 this.props.userInfo 获取数据
- 参数2是函数,函数接收 store 中的 dispatch作为第一个参数,通常返回提交action的一些方法,例子中的App组件可以通过 this.props.initCity(cityName) 提交action
- <Router history={ history }> : 传递history 给所有组件,组件就可以通过 this.props.history.push('路由')跳转页面, this.props.history.goBack() 方法返回
- <Route path="/city" component={ City }></Route> : 路由配置
例子中的:reducers
import { combineReducers } from 'redux'
export function detailInfo(state = {}, action) {
switch (action.type) {
case 'GET_DETAIL_INFO':
return {
...state,
info: action.payload.info
}
case 'GET_COMMENT_LIST':
return {
...state,
comments: action.payload.comments
}
default:
return state
}
}
const initialState = {page: 0, likeList: [] }
export function userInfo(state = initialState, action) {
switch (action.type) {
case 'USER_CURRENTCITY':
return {
...state,
cityName: action.payload.cityName,
userName: '小名'
}
case 'SAVE_HOMEAD':
return {
...state,
homeAd: action.payload.homeAd
}
case 'SAVE_LIKELIST':
return {
...state,
page: state.page + 1,
likeList: state.likeList.concat(action.payload.likeList)
}
case 'SET_ISLOADINGLIKELIST_FLAG':
return {
...state,
isLoading: action.payload.isLoading
}
default:
return state
}
}
export default combineReducers({
userInfo,
detailInfo
})
代码分析:combineReducers: 接收一个拆分后 reducer 函数组成的对象,返回一个新的 Reducer 函数
代码中的:所有action ,案例只列举:initCity
import axois from 'axios'
export function getDetailInfo(shopId) {
return dispatch => axois.get(`/api/detail/info/${shopId}`).then((res) => {
dispatch(saveDetailInfo(res.data))
}).catch((error) => {
console.log(error)
})
}
export function saveDetailInfo(res) {
return {
type: 'GET_DETAIL_INFO',
payload: {
info: res
}
}
}
export function getComments(shopId) {
return axois.get(`/api/detail/comment/${shopId}`).then((res) => {
dispatch(saveComments(res.data))
}).catch((error) => {
console.log(error)
})
}
export function saveComments(res) {
return {
type: 'GET_COMMENT_LIST',
payload: {
comments: res
}
}
}
- axois: ajax请求的插件
- getDetailInfo:
- 该action 返回了一个发送ajax异步请求的函数
- 异步请求成功后 触发一个action : dispatch(saveDetailInfo(res.data))
- 普通的action 通常返回一个对象,它之所以能够返回函数,是由于利用了插件“thunk'”,这个是异步action 的写法
City
import React from 'react'
import { connect } from 'react-redux'
import { updateCity } from '../../actions/userinfo'
import Header from '../../components/Header'
import CityList from '../../components/CityList'
import CurrentCity from './subpages/CurrentCity'
class City extends React.Component {
render() {
return (
<div>
<Header title="选择城市" goBack={ this.goBack.bind(this) }></Header>
<CurrentCity currentCityName={ this.props.userInfo.cityName }></CurrentCity>
<CityList chooseCity= { this.chooseCity.bind(this) }></CityList>
</div>
)
}
goBack() {
this.props.history.goBack()
}
chooseCity(cityName) {
localStore.setItem('USER_CURRENT_CITY', cityName)
this.props.initCity(cityName)
this.props.history.goBack()
}
}
function mapStateToProps(state) {
return {
userInfo: state.userInfo
}
}
function mapDispatchToProps(dispatch, ownProps) {
return {
initCity: (cityName) => {
dispatch(updateCity(cityName))
}
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(City)
goBack={ this.goBack.bind(this) } : 将组件本身的goBack方法,传递给 Header 组件 , bind的作用是:在Header组件调用该方法时,上下文为City组件的 this
Header
import React from 'react'
class Header extends React.Component {
render() {
return (
<div id="common-header">
<span className="back-icon" onClick={ this.clickHandle.bind(this) }>
<i className="icon-chevron-left"></i>
</span>
<h1>{ this.props.title }</h1>
</div>
)
}
clickHandle() {
window.history.back()
}
}
export default Header
Header组件并没有用connect包装,因为它是纯显示的组件,只有跟业务相关的组件,才会用connect容器包装
react-router + redux + react-redux 的例子与分析的更多相关文章
- [Redux] Adding React Router to the Project
We will learn how to add React Router to a Redux project and make it render our root component. Inst ...
- [Web 前端] React Router v4 入坑指南
cp from : https://www.jianshu.com/p/6a45e2dfc9d9 万恶的根源 距离React Router v4 正式发布也已经过去三个月了,这周把一个React的架子 ...
- React躬行记(13)——React Router
在网络工程中,路由能保证信息从源地址传输到正确地目的地址,避免在互联网中迷失方向.而前端应用中的路由,其功能与之类似,也是保证信息的准确性,只不过来源变成URL,目的地变成HTML页面. 在传统的前端 ...
- React Router 4.x 开发,这些雷区我们都帮你踩过了
前言 在前端框架层出不穷的今天,React 以其虚拟 DOM .组件化开发思想等特性迅速占据了主流位置,成为前端开发工程师热衷的 Javascript 库.作为 React 体系中的重要组成部分:Re ...
- React Router V4发布
React Router V4 正式版发布,该版本相较于前面三个版本有根本性变化,遵循 Just Component 的 API 设计理念. 本次升级的主要变更有: 声明式 Declarative 可 ...
- React Router 4.0 体验
React Router 4.0 (以下简称 RR4) 已经正式发布,它遵循React的设计理念,即万物皆组件.所以 RR4 只是一堆 提供了导航功能的组件(还有若干对象和方法),具有声明式(声明式编 ...
- React Router基础使用
React是个技术栈,单单使用React很难构建复杂的Web应用程序,很多情况下我们需要引入其他相关的技术 React Router是React的路由库,保持相关页面部件与URL间的同步 下面就来简单 ...
- React Router基础教程
React是个技术栈,单单使用React很难构建复杂的Web应用程序,很多情况下我们需要引入其他相关的技术 React Router是React的路由库,保持相关页面部件与URL间的同步 下面就来简单 ...
- React Router教程
React Router教程 React项目的可用的路由库是React-Router,当然这也是官方支持的.它也分为: react-router 核心组件 react-router-dom 应用于浏览 ...
- 最新的chart 聊天功能( webpack2 + react + router + redux + scss + nodejs + express + mysql + es6/7)
请表明转载链接: 我是一个喜欢捣腾的人,没事总喜欢学点新东西,可能现在用不到,但是不保证下一刻用不到. 我一直从事的是依赖angular.js 的web开发,但是我怎么能一直用它呢?看看最近火的一塌糊 ...
随机推荐
- P4718 【模板】Pollard-Rho算法
题面 传送门 题解 题解 太神仙了学不来orz //minamoto #include<bits/stdc++.h> #define R register #define ll long ...
- 洛谷P2518 [HAOI2010]计数
题目描述 你有一组非零数字(不一定唯一),你可以在其中插入任意个0,这样就可以产生无限个数.比如说给定{1,2},那么可以生成数字12,21,102,120,201,210,1002,1020,等等. ...
- Mysql INNER JOIN
1.MySQL INNER JOIN子句将一个表中的行与其他表中的行进行匹配,并允许从两个表中查询包含列的行记录. 2.INNER JOIN子句是SELECT语句的可选部分,它出现在FROM子句之后. ...
- CF385C Bear and Prime Numbers 数学
题意翻译 给你一串数列a.对于一个质数p,定义函数f(p)=a数列中能被p整除的数的个数.给出m组询问l,r,询问[l,r]区间内所有素数p的f(p)之和. 题目描述 Recently, the be ...
- java Response 设置中文编码
response.setHeader("Content-type", "text/html;charset=UTF-8"); response.setChara ...
- 解决SharePoint密码更新后,创建Web Application 失败
问题在sharepoint central administration中通过Configuration Wizards来创建一个web application,出现如下错误: The passwor ...
- 深入了解Json Web Token之概念篇
https://www.freebuf.com/articles/web/180874.html http://www.ruanyifeng.com/blog/2018/07/json_web_tok ...
- 在Pycharm上编写WordCount程序
本篇博客将给大家介绍怎么在PyCharm上编写运行WordCount程序. 第一步 下载安装PyCharm 下载Pycharm PyCharm的下载地址(Linux版本).下载完成后你将得到一个名叫: ...
- linux中mysql,mongodb,redis,hbase数据库操作
.实验内容与完成情况:(实验具体步骤和实验截图说明) (一) MySQL 数据库操作 学生表 Student Name English Math Computer zhangsan lisi 根据上面 ...
- docker 镜像保存为文件及从文件导入镜像的方法
1.保存镜像为文件 docker save -o 要保存的文件名 要保存的镜像 举例: docker save -o 2.从文件载入镜像 docker load --input 文件或者docker ...