react + redux 实现幻灯片
写在前面:
这一篇是我 使用scss + react + webpack + es6实现幻灯片 的进阶篇,效果请点我,将会使用上redux的基础用法,因为一开始没有理解好redux的用法,单纯看文档,实现Todo List效果。但却没有形成思路,当想改造成自己东西时,一脸懵逼,无从下手。后面动手整理思路,以下将会整理我的学习思路,如有出错,请各位指教。
首先
1.你有接触React 同时研究了 Redux,没有的话这里有不错的学习资源。 Redux中文文档 Redux 指导与Redux 式编程 Redux 简明教程
2.在火狐或者谷歌下载插件 React Devtools 这个将会原原本本的看到数据的传递,对于理解数据流动,必不可少
3.这一篇是基于我的前一篇基础实现的,如果没看过,建议你熟悉一下。
Redux 学习思路
下面的图是store的数据流动的方式
数据流程:1.通过store.dispatch 方法触发action
2.相应的reducers更新state
3.调用subscribe方法注册执行回调
Action Creator => action => store.dispatch(action) => reducer(state,action) => next state
这里面有一个我经常混淆的地方:
action:描述一个状态/动作 {type :' Set_Center_Filter ' , index} 这里面的type是必不可少的标识,比如是新增还是修改的标识。
actionCreator:创造一个action,是一个函数
- export function setCenterFilter(index){
- return {type : Set_Center_Filter , index}
- }
dispatch:dispatch(setCenterFilter(index)) 里面的 setCenterFilter 就是actionCreator的函数。dispatch(setCenterFilter 返回的action)。
reducer:(将是创建store的基础)当dispatch执行之后,reducer就被自动执行,返回新的state
整体数据流动:
1.最外层的数据由 <Provider store={store}> <APP/> </Provider > 里面的store提供,让容器里的 Connect(App)图1知道从哪里获得store对象(state来源)当做其自身props【1】
2.store由reducers通过 createCtore提供
3. reducers 由combineReducers 集合多个 reducer (todos , visibilityFilter)(整合到【1】里面的store)
4.以新增的todo为例,返回为 原数据加上新的数据,其被触发方式为dispatch(action)
5.容器组件的disptach(action) 通过connect将需要过滤后的state传给【1】中的<App/> 当做其props图2
这就是整条数据链,至于剩下的组件,只需要拿到父组件的props当做自己的props,进行React的操作。
以上的内容比较羞涩难懂,还是需要自己好好琢磨。
接下来就是我的正文了,实现上一次的整合。
目录结构:
- |----build //编译的环境
- |--server.js
- |--webpack.config.js
- |----src //项目主入口
- |--action
- |--components
- |--containers
- |--reducers
- |--index.html
- |--index.js
- |----static //静态文件
- |--css
- |--data
- |--imgs
- |--package.json
- |--.babelrc
项目分析:
1.分成两个组件:图片展示,按钮控制(两个组件都需要imgs数据)
2.reducers分为两部分:imgs数据,current 用于存储展示的索引
3.按钮点击改变current里面设置的索引参数(action.index),根据索引参数,改变各个展示图片的 isCenter属性。
4.基于上面的机制,action只有一个 ‘Set_Center_Filter’,用于判断按钮点击这个动作。
接下来是我自己一般的创建的流程
各组组件先创建,然后模拟父组件本身就有props数据,这一步和React无异。
components/App.js
- class App extends Component{
- render(){return(
- <div className="slider">
- <ShowPic
- imgs = [
- {
- "img": "1.jpg",
- "h1": "Creative",
- "h2": "DUET",
"isCenter":"true",
"right" :"true"
},- {
- "img": "2.jpg",
- "h1": "Friendly",
- "h2": "Happy",
"isCenter":"true",
"right" :"true"- }]/>
- <SetCenterFilter
- imgs= [
- {
- "img": "1.jpg",
- "h1": "Creative",
- "h2": "DUET",
"isCenter":"true",
"right":"true"- },
- {
- "img": "2.jpg",
- "h1": "Friendly",
- "h2": "Happy",
"isCenter":"true",
"right":"true"- }]
- />
- </div>
- )
- }
- }
containers/ShowPic.js
- import React,{Component} from 'react'
- import MainI from './MainI'
- export default class ShowPic extends Component{
- render(){
- return(
- <div className="main">
- {this.props.imgs.map((imgi , index)=>
- <MainI {...imgi}
- key={index}
- isCenter={this.props.current == index} />
- )}
- </div>
- )
- }
- }
containers/SetCenterFilter.js
- import React,{Component} from 'react'
- import CtrlI from './CtrlI'
- export default class SetCenterFilter extends Component{
- render() {
- return(
- <div className="ctrl">
- {this.props.imgs.map((imgi , index) =>
- <CtrlI {...imgi}
- key={index}
isCenter = {this.props.current == index}- onClick={()=>this.props.onCenterClick(index)}/>
- )}
- </div>
- )
- }
- }
containers/CtrlI.js
- import React,{Component} from 'react'
- export default class CtrlI extends Component{
- render(){
- var {isCenter , img , onClick} = this.props;
- var ctrlClassName = 'ctrl-i' + (isCenter? ' ctrl-i_active' :'');
- return(
- <a className={ctrlClassName} onClick={onClick}>
- <img src={img} alt=""/>
- </a>
- )
- }
- }
containers/MainI.js
- import React,{Component} from 'react'
- export default class MainI extends Component{
- render(){
- var {isRight , isCenter , h1 ,h2 ,img} = this.props;
- var mainClassName = (isRight?'main-i main-i_right':'main-i')+
- (isCenter ?' main-i_active':'');
- return(
- <div className={mainClassName}>
- <div className="caption">
- <h2>{h1}</h2>
- <h3>{h2}</h3>
- </div>
- <img src={img} alt=""/>
- </div>
- )
- }
- }
上面的步奏基本和React没有什么太大区别。
Action
- export const Set_Center_Filter = "Set_Center_Filter";
- export function setCenterFilter(index){
- return {type : Set_Center_Filter , index}
- }
定义Action一定要对自己的场景熟悉,比如我的幻灯片只需要点击更换state,所以只有一个action改变事件。
Reducer
- import {combineReducers} from 'redux'
- import { Set_Center_Filter } from '../actions/index'
- /*
- * 需要npm install json-loader
- * 识别路径中的JSON对象
- * */
- var imgData = require('../../static/data/imgDatas.json');
- /* @type (function(){})() 立即执行函数
- * @param imageDatasArr Json对象
- * @return new JSON
- * @功能 1.将图片名信息转成图片URL路径信息
- * 2.根据 奇偶 添加isRight属性
- * */
- imgData.forEach((item,index)=>{
- item.isRight = index % 2;
- item.img = '../static/imgs/'+item.img;
- })
- //单纯的将 imgData 保存给state
- function imgs(state = imgData){
- return state
- }
- function current(state , action){
- switch(action.type){
- case Set_Center_Filter:
- return action.index;
- default:
- return 0;
- }
- }
- const SliderApp = combineReducers({
- imgs,
- current
- })
- export default SliderApp
这一段相当于核心步奏,通过改变current,返回对应索引。并在按钮点击时候对比后,添加class "_active"
components/App.js 修改内容
- class App extends Component{
- render(){
- const {imgs,current} = this.props;
- return(
- <div className="slider">
- <ShowPic
- imgs={imgs}
- current = {current}/>
- <SetCenterFilter
- imgs={imgs}
- current = {current}
- onCenterClick ={index => this.props.setCurrent(index)}/>
- </div>
- )
- }
- }
- function mapStateToProps(state) {
- return {
- imgs: state.imgs,
- current : state.current
- };
- }
- function mapDispatchToProps(dispatch) {
- return {
- setCurrent: (index) => dispatch(setCenterFilter(index))
- };
- }
- export default connect(mapStateToProps,mapDispatchToProps)(App)
- connect用来连接React 与 Redux。
onCenterClick 点击之后就会dispatch{type:Set_Center_Filter , index} 来更新store/state
- connect将 state 的imgs属性映射到了 ShowPic SetCenterFilter 的 this.props 属性中,同时也把针对特定的Action Creator 的 dispatch 方法传递给了 this.props。这样在 ShowPic SetCenterFilter 中仅仅通过 this.props 就可以完成 action dispatch 和 应用程序状态获取的动作
如果connect 函数省掉第二个参数,connect(mapStateToProps)(App)
,那么 dispatch
方法会被直接传递给 this.props
。这不是推荐的方式,因为这意味着 App 需要了解 dispatch
的功能和语义了
最后就是
Index.js
- import React from 'react'
- import {render} from 'react-dom'
- import {createStore} from 'redux'
- import {Provider} from 'react-redux'
- import App from './containers/App'
- import SliderApp from './reducers/reducers'
- let store = createStore(SliderApp)
- render(
- <Provider store={store}>
- <App/>
- </Provider>,
- document.getElementById('Pic_slider')
- )
最后一步就是用Provider让App.js的connect知道从哪里获得store数据
以上就是这个React+Redux 实现幻灯片的思想,思想是自己的理解,如果有出错,还望大家指出,一起学习。非常感谢楼下的朋友,帮我指正了错误。
以上的代码均可以在我的Github上找到,与君共勉。
如果是原创文章,转载请注明出处!!!
by 邱XX:http://www.cnblogs.com/QRL909109/p/5826895.html
react + redux 实现幻灯片的更多相关文章
- webpack+react+redux+es6开发模式
一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入 ...
- react+redux教程(六)redux服务端渲染流程
今天,我们要讲解的是react+redux服务端渲染.个人认为,react击败angular的真正“杀手锏”就是服务端渲染.我们为什么要实现服务端渲染,主要是为了SEO. 例子 例子仍然是官方的计数器 ...
- react+redux教程(五)异步、单一state树结构、componentWillReceiveProps
今天,我们要讲解的是异步.单一state树结构.componentWillReceiveProps这三个知识点. 例子 这个例子是官方的例子,主要是从Reddit中请求新闻列表来显示,可以切换reac ...
- react+redux官方实例TODO从最简单的入门(6)-- 完结
通过实现了增-->删-->改-->查,对react结合redux的机制差不多已经了解,那么把剩下的功能一起完成吧 全选 1.声明状态,这个是全选状态 2.action约定 3.red ...
- react+redux官方实例TODO从最简单的入门(1)-- 前言
刚进公司的时候,一点react不会,有一个需求要改,重构页面!!!完全懵逼,一点不知道怎么办!然后就去官方文档,花了一周时间,就纯react实现了页面重构,总体来说,react还是比较简单的,由于当初 ...
- 重写官方TodoList,对于初学react+redux的人来说,很有好处
虽然官网的TodoList的例子写的很详细,但是都是一步到位,就是给你一个action,好家伙,全部都写好了,给你一个reducer,所有功能也是都写好了,但是我们这些小白怎么可能一下就消化那么多,那 ...
- react+redux教程(四)undo、devtools、router
上节课,我们介绍了一些es6的新语法:react+redux教程(三)reduce().filter().map().some().every()....展开属性 今天我们通过解读redux-undo ...
- react+redux教程(三)reduce()、filter()、map()、some()、every()、...展开属性
reduce().filter().map().some().every()....展开属性 这些概念属于es5.es6中的语法,跟react+redux并没有什么联系,我们直接在https:// ...
- react+redux教程(二)redux的单一状态树完全替代了react的状态机?
上篇react+redux教程,我们讲解了官方计数器的代码实现,react+redux教程(一).我们发现我们没有用到react组件本身的state,而是通过props来导入数据和操作的. 我们知道r ...
随机推荐
- 题解 P2762 【太空飞行计划问题】
P2762 太空飞行计划问题 题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合E={E1,E2,-,Em},和进 ...
- vmware中无法ping通主机的问题
虚拟机使用NAT方式运行一段时间后,发现无法ping通主机(物理机),显示错误如下 ipconfig如下 查看虚拟机中的网络连接,显示"未识别网络" 分析: 查看了网络上的一些资料 ...
- 如何识别字符串是否是UTF-8编码的
我们先要弄明白原始字符串里的字符用的是何种编码方式,运行如下 string tmp = "你好world"; for(int i=0;i<tmp.size();++i) { ...
- Ubuntu+NDK编译openssl
为了Android上使用libcurl且支持HTTPS协议,需要依赖openssl,因此先来了解一下如何编译OpenSSL1.编译ARM下的共享库(默认的)我使用的是guardianproject的o ...
- 最短路+找规律 Samara University ACM ICPC 2016-2017 Quarterfinal Qualification Contest L. Right Build
题目链接:http://codeforces.com/gym/101149/problem/L 题目大意:有n个点(其实是n+1个点,因为编号是0~n),m条有向边.起点是0,到a和b两个节点,所经过 ...
- CF821 B. Okabe and Banana Trees 简单数学
Link 题意:给出一条直线,在直线上取一点,其垂直x,y轴作成一个,求矩阵中所有包含的点的x,y坐标之和的最大值. 思路:对于一个任意一点我们计算公式,对于任意一点$(x, y)$,有$(x+y)^ ...
- HDU 4990 Reading comprehension 简单矩阵快速幂
Problem Description Read the program below carefully then answer the question.#pragma comment(linker ...
- Python学习笔记(四十七)SMTP发送邮件
摘抄自:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432005226 ...
- 强大的jQuery网格插件 ParamQuery
ParamQuery是一种轻量级的jQuery网格插件,基于用于用户界面控制.具有一致API的优秀设计模式jQueryUI Widget factory创建,能够在网页上展示各种类似于Excel和Go ...
- 【CodeForces】626 F. Group Projects 动态规划
[题目]F. Group Projects [题意]给定k和n个数字ai,要求分成若干集合使得每个集合内部极差的总和不超过k的方案数.n<=200,m<=1000,1<=ai< ...