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开发,但是我怎么能一直用它呢?看看最近火的一塌糊 ...
随机推荐
- memcache (持续了解ing...)
mem cache 英[kæʃ] 美[kæʃ]vt. 贮藏; memcache是一套分布式的高速缓存系统,目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的.需要频繁访问数据库的网站访问速度提 ...
- CF912E Prime Gift 数学
Opposite to Grisha's nice behavior, Oleg, though he has an entire year at his disposal, didn't manag ...
- kuangbin专题七 POJ3264 Balanced Lineup (线段树最大最小)
For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One d ...
- Codeforces Round #526 (Div. 2) D. The Fair Nut and the Best Path 树上dp
D. The Fair Nut and the Best Path 题意:给出一张图 点有权值 边也要权值 从任意点出发到任意点结束 到每个点的时候都可以获得每个点的权值,而从边走的时候都要消耗改边的 ...
- linux 环境下tomcat中部署jfinal项目
tomcat中部署jfinal项目 问题现象如下图 问题描述: 我在自己的windows7系统上tomcat下面跑这个项目没有任何问题吗,但是当我把项目上传到linux服务器上的tomcatwebap ...
- Kibana6.x.x——导航权限控制入门
按如下图所示设置: 用该用户登录后,界面如图所示: 但遗憾的是,根据官方论坛的说法,其它的导航隐藏控制,暂时还不支持. 参考:https://discuss.elastic.co/t/hide-ina ...
- System.Collections.Generic.List<T> 与 System.Collections.ArrayList
[推荐] System.Collections.Generic.List<T> [原因] 泛型集合类List<T>在操作值类型的集合时可以不进行 装箱/拆箱 处理. 使得性能较 ...
- yum安装zabbix故障报错
装zabbix时报错 [root@zabbix ~]# rpm -ivh zabbix-server-mysql-2.2.3-1.el6.x86_64.rpm zabbix-web-mysql-2.2 ...
- 前端https调用后端http
昨晚发生了一个,很........的事 我前端的域名 和后端的域名 都没有做认证,前端的访问的80 调用的后端80 然后我给前端的域名做了认证ssl,但是调用后端的时候报错 原因是 https 调 ...
- Qt中的布局管理器
1. 布局管理器提供相关的类对界面组件进行布局管理,能够自动排列窗口中的界面组件,窗口变化后能自动更新界面组件的大小. 2. QLayout是Qt布局管理器的抽象基类,通过继承QLayout实现了功能 ...