项目目录

首先,一个基于React + Redux + React-Router的项目目录可以按照我下方的图片来构建:

其中assets目录用于存放项目的静态资源,如css/图片等,src目录则用于存放React的组件资源。

入口文件配置

在webpack的配置项中,我们需要一个或多个入口文件,这里我就不展示关于package.json及webpack.config.js的文件配置,最后我会提供整个项目的下载链接供大家参考。这里我主要介绍下入口文件index.js的配置说明。

import React from 'react'  // 引入React
import { render } from 'react-dom' // 引入render方法
import { Provider } from 'react-redux' // 利用Provider可以使我们的 store 能为下面的组件所用
import { Router, browserHistory } from 'react-router' // Browser history 是由 React Router 创建浏览器应用推荐的 history
import { syncHistoryWithStore } from 'react-router-redux' // 利用react-router-redux提供的syncHistoryWithStore我们可以结合store同步导航事件import finalCreateStore from './src/store/configureStore'  //引入增强后的store
import DevTools from './src/containers/DevTools'  // 引入Redux调试工具DevTools
import reducer from './src/reducers'  // 引入reducers集合
import routes from './src/routes'   // 引入路由配置import './assets/css/bootstrap.min.css'  // 引入样式文件// 给增强后的store传入reducer
const store = finalCreateStore(reducer)// 创建一个增强版的history来结合store同步导航事件
const history = syncHistoryWithStore(browserHistory, store)render({/* 利用Provider包裹页面 */}<Provider store={store}><div>{/* 渲染根路由 */}<Router history={history} routes={routes} />{/* 渲染调试组件 */}<DevTools /></div></Provider>,document.getElementById('mount')
)

在入口文件中我们尽量只需要保留基本的东西,其余的配置代码我们可以放到相应的配置文件中去,比如路由、reducers及store的配置等。这里我都把它们放置到了独立的js中,只在入口文件中通过import引入,这样管理和维护起来会非常方便,但也会相应增加理解的难度,然而一旦上手就会很容易。那么接下来我们再来看下store配置吧。

store配置

import thunk from 'redux-thunk' // redux-thunk 支持 dispatch function,并且可以异步调用它
import createLogger from 'redux-logger' // 利用redux-logger打印日志
import { createStore, applyMiddleware, compose } from 'redux' // 引入redux createStore、中间件及compose
import DevTools from '../containers/DevTools' // 引入DevTools调试组件// 调用日志打印方法
const loggerMiddleware = createLogger()// 创建一个中间件集合
const middleware = [thunk, loggerMiddleware]// 利用compose增强store,这个 store 与 applyMiddleware 和 redux-devtools 一起使用
const finalCreateStore = compose(applyMiddleware(...middleware),DevTools.instrument(),
)(createStore)export default finalCreateStore

这里我们需要了解中间件(Middleware)的概念。middleware 是指可以被嵌入在框架接收请求到产生响应过程之中的代码,你可以在一个项目中使用多个独立的第三方 middleware,如上面的redux-thunk和redux-logger。详细资料请参考官方文档:
http://cn.redux.js.org/docs/advanced/Mid...

路由配置

上面的入口文件配置中我们把路由配置部分单独放到了routes.js的文件中,这里我们就来看下其配置:

import React from 'react' // 引入react
import { Route, IndexRoute } from 'react-router' // 引入react路由
import { App, Home, Foo, Bar, Antd } from './containers' // 引入各容器组件export default (<Route path="/" component={App}><IndexRoute component={Home}/><Route path="index" component={Home}/><Route path="foo" component={Foo}/><Route path="bar" component={Bar}/><Route path="antd" component={Antd}/></Route>
)

这里的路由配置和不使用redux时候是一样的,唯一需要了解的是容器组件和展示组件的概念。上面配置文件中的路由加载的组件都可以认为是容器组件。
(1)顾名思义,展示组件包含在容器组件中,只用作页面展示,不会定义数据如何读取如何改变,只通过this.props接受数据和回调函数;
(2)而容器组件中包含各展示组件的数据,即Props,它们为展示组件或其他组件提供数据和方法。
我们应该把它们放在不同的文件夹中,以示区别,如上面“项目目录”中的containers和components文件夹分别存放容器组件和展示组件。具体说明可以参考文章:http://www.jianshu.com/p/6fa2b21f5df3

根组件配置

import React, { Component } from 'react' // 引入React
import { Link } from 'react-router' // 引入Link处理导航跳转export default class App extends Component {render() {return(<div><nav className="navbar navbar-default"><div className="container-fluid"><div className="navbar-header"><span className="navbar-brand" href="#"><Link to="/">Redux</Link></span></div><ul className="nav navbar-nav"><li><Link to="/index" activeStyle={{color: '#555', backgroundColor: '#e7e7e7'}}>计数器</Link></li><li><Link to="/foo" activeStyle={{color: '#555', backgroundColor: '#e7e7e7'}}>静态数据</Link></li><li><Link to="/bar" activeStyle={{color: '#555', backgroundColor: '#e7e7e7'}}>动态数据</Link></li><li><Link to="/antd" activeStyle={{color: '#555', backgroundColor: '#e7e7e7'}}>结合antd</Link></li></ul></div></nav><div className="panel panel-default"><div className="panel-body">{ this.props.children }</div></div></div>)}
}

整个根组件App.js主要渲染了整个应用的导航和可变区域,这其实和Redux没有关系。需要注意的是to中的URL地址需要和routes.js中的path地址名称一致。

写到这里还没有介绍Redux中的Action及Reducer的配置,那么接下来就来介绍下。

Action配置

import { INCREASE, DECREASE, GETSUCCESS, REFRESHDATA } from '../constants'  // 引入action类型名常量
import 'whatwg-fetch'  // 可以引入fetch来进行Ajax// 这里的方法返回一个action对象
export const increase = n => {return {type: INCREASE,amount: n}
}export const decrease = n => {return {type: DECREASE,amount: n}
}export const refreshData = () => {return {type: REFRESHDATA}
}export const getSuccess = (json) => {return {type: GETSUCCESS,json}
}function fetchPosts() {return dispatch => {return fetch('data.json').then((res) => { console.log(res.status); return res.json() }).then((data) => {dispatch(getSuccess(data))}).catch((e) => { console.log(e.message) })}
}// 这里的方法返回一个函数进行异步操作
export function fetchPostsIfNeeded() {// 注意这个函数也接收了 getState() 方法// 它让你选择接下来 dispatch 什么return (dispatch, getState) => {return dispatch(fetchPosts())}
}

上面返回一个action对象的方法叫做“action 创建函数”,它就是生成action的方法,也是store数据的唯一来源。
上面返回一个函数的方法叫做“异步action”,这里使用的是Redux Thunk middleware,要引入redux-thunk这个专门的库才能使用,这样我们就可以实现异步Ajax请求改变状态等功能了。

Reducer配置

reducers/count.js
// reducers/count.js
import { INCREASE, DECREASE, GETSUCCESS, REFRESHDATA } from '../constants' // 引入action类型常量名// 初始化state数据
const initialState = {number: 1,lists: [{text: '整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。'}, {text: '惟一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。'},{text: '为了描述 action 如何改变 state tree ,你需要编写 reducers。'},{text: '就是这样,现在你应该明白 Redux 是怎么回事了。'}],data: []
}// 通过dispatch action进入
export default function update(state = initialState, action) {// 根据不同的action type进行state的更新switch(action.type) {case INCREASE:return Object.assign({}, state, { number: state.number + action.amount })breakcase DECREASE:return Object.assign({}, state, { number: state.number - action.amount })breakcase GETSUCCESS:return Object.assign({}, state, { data: action.json })case REFRESHDATA:return Object.assign({}, state, { data: [] })default:return state}
}

reducers/index.js
// reducers/index.js
import { combineReducers } from 'redux' // 利用combineReducers 合并reducers
import { routerReducer } from 'react-router-redux' // 将routerReducer一起合并管理
import update from './count' // 引入update这个reducerexport default combineReducers({update,routing: routerReducer
})

这里我们主要需要了解如何通过combineReducers来合并reducers,同时在进入reducer方法后我们必须返回一个state的处理结果来更新state状态,否则会报错。还需注意的是在合并reducers的时候,需要加上routerReducer这个由“react-router-redux”提供的reducer来管理路由的状态更新。

容器组件

上文提到了容器组件和展示组件的区别和含义,这里我们需要在容器组件使用connect来搭配Redux来进行状态管理,这是很关键的一步。

import React, { Component, PropTypes } from 'react' // 引入React
import { connect } from 'react-redux' // 引入connect
import List from '../components/List'  // 引入展示组件Listexport default class Foo extends Component {render() {// 通过this.props获取到lists的值const { lists } = this.propsreturn(<div><ul className="list-group">{将值传入展示组件}{ lists.map((e, index) => <List text={e.text} key={index}></List>)}</ul></div>)}
}// 验证组件中的参数类型
Foo.propTypes = {lists: PropTypes.arrayOf(PropTypes.shape({text: PropTypes.string.isRequired}).isRequired).isRequired
}// 获取state中的lists值
const getList = state => {return {lists: state.update.lists}
}// 利用connect将组件与Redux绑定起来
export default connect(getList)(Foo)

在容器组件中我们需要获取state中的初始状态的时候,我们需要使用connect。任何一个从 connect() 包装好的组件都可以得到一个 dispatch 方法作为组件的 props,以及得到全局 state 中所需的任何内容。connect() 的唯一参数是 selector。此方法可以从 Redux store 接收到全局的 state,然后返回组件中需要的 props。详资料请参考文档:http://cn.redux.js.org/docs/basics/Usage...

展示组件

上面的容器组件中引入了一个展示组件List,我们来看下它的代码:

import React, { Component, PropTypes } from 'react'export default class List extends Component {render() {return(<li className="list-group-item">{this.props.text}</li>)}
}List.propTypes = {text: PropTypes.string.isRequired
}

从中我们可以发现,展示组件没有connect的方法,数据是通过this.props来获取的,这样的方式能够是数据的变化清晰可查,便于管理和维护。

转载于:https://www.cnblogs.com/crazycode2/p/8655338.html

redux 存值 及 取值 的操作相关推荐

  1. python嵌套字典取值_python嵌套字典比较值与取值的实现示例

    python嵌套字典比较值与取值的实现示例 本文通过示例给大家介绍了python嵌套字典比较值,取值,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 示例代码 #取值import t ...

  2. mysql1193 HY000_[MySQL参数取值] Status取值ERROR 1193 (HY000): Unknown system_MySQL

    bitsCN.com [MySQL参数取值] Status取值ERROR 1193 (HY000): Unknown system variable 'Innodb_buffer_pool_read_ ...

  3. python如何使用字典中的值并进行比较_python嵌套字典比较值与取值的实现示例

    前言 本文通过示例给大家介绍了python嵌套字典比较值,取值,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 示例代码 #取值import types allGuests = {' ...

  4. Java基本数据类型默认值和取值范围详解

    Java基本数据类型有哪些?Java中的基本数据类型有,byte.short.int.long.float.double.char和.boolean这些,接下我们来了解一下它们的默认值和取值范围是怎样 ...

  5. java jquery怎么取值_jquery 取值

    jquery radio取值,checkbox取值,select取值,radio选中,checkbox选中,select选中,及其相关 获取一组radio被选中项的值 var item = $('in ...

  6. java map 允许null值,Map取值方法,其中取得多种值,避免null值转换

    ~~~ import java.math.BigDecimal; import java.util.Date; import java.util.Map; /** * * Map取值方法,其中取得多种 ...

  7. html 页间传送数据,js 不同页面间传递值并取值,html不同页面间数据传递

    以前没用到过页面间传递参数再从后台获取数据,自己总结了一些. 先说需求:现在有页面pageA.html 和页面pageB.html,页面pageA.html中有一事件,当这个事件触发时会打开页面pag ...

  8. js 不同页面间传递值并取值

    原博主地址:http://blog.csdn.net/web_xyk/article/details/47857033 以前没用到过页面间传递参数再从后台获取数据,然后搜索了一下. 发现了一个比较好的 ...

  9. Jmeter中唯一值-UUID取值(截取指定长度、去除“-”)

    Jmeter脚本参数化时,对uuid值去-并截取一定长度. 在jmeter的BeanShell Sampler 中,添加以下代码即可实现UUID值的去除"-",并根据需要截取字符串 ...

最新文章

  1. pinctrl虚拟spi的linux驱动,linux内核pinctrl驱动的理解和总结
  2. 通过java.net.URLConnection发送HTTP请求的方法
  3. 微软Build2021今日召开,共同期待VS2022+.NET6!
  4. MacOS 的软件包管理工具 MacPorts
  5. js时间搓化为今天明天_来揭秘化妆品为啥会搓泥?
  6. html点击标签c,html - 标签并以html形式输入点击其他提交按钮(所有浏览器) - 堆栈内存溢出...
  7. Linux系统(二)常用命令、进程管理
  8. BAT 解密:一张图概括互联网公司的标准技术架构
  9. spring云化架构迁移 (一)
  10. 【TLSR825x】windows下开发环境搭建,固件烧录方法
  11. linux快捷键停止抓包命令,【linux命令】Linux抓包命令tcpdump以及常见抓包使用方法...
  12. jzoj5629 【NOI2018模拟4.4】Map (业界毒瘤仙人掌缩环,线段树合并)
  13. nested exception is java.sql.SQLException: Data truncated for column 'PassWord' at row 72
  14. 教师学计算机信息,计算机教师
  15. uniApp实现热更新
  16. 网上买电信电话卡又被欺骗百元
  17. 电话簿管理系统(超详细)
  18. Using React, Typescript, and Webpack with Visual Studio 2015
  19. 服务器看门狗芯片电路图,看门狗芯片MAX708的工作原理及数 - 电源设计应用 - 电子发烧友网...
  20. LeetCode 912. 排序数组(Java)

热门文章

  1. mysql inodb主键bug_MySQL的这个bug,坑了多少人?
  2. java中 移位运算_java中关于移位运算符的demo与总结(推荐)
  3. Web负载均衡学习笔记之四层和七层负载均衡的区别
  4. SpringBoot 2.x 集成 Redis
  5. 98. Validate Binary Search Tree
  6. C#重写Equals方法步骤
  7. 关于J2SE/Jsp/Sping/Hibernate/Struts2的视频下载
  8. mono for android 使用Tab 控件
  9. Takeown--夺取文件or文件夹所有权
  10. 【Vegas原创】分别用Toad、EM解表锁