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.最外层的数据由 里面的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】中的 当做其props图2

这就是整条数据链,至于剩下的组件,只需要拿到父组件的props当做自己的props,进行React的操作。

以上的内容比较羞涩难懂,还是需要自己好好琢磨。

接下来就是我的正文了,实现上一次的整合。

目录结构: |----build //编译的环境 |--server.js |--webpack.config.js|----data-src //项目主入口 |--action |--components |--containers |--reducers |--index.html |--index.js|----static //静态文件 |--css |--data |--imgs|--package.json|--.babelrc

项目分析:

1.分成两个组件:图片展示,按钮控制(两个组件都需要imgs数据)

2.按钮点击改变state里面设置的isCenter参数,从而改变图片展示,按钮控制里面的图片。

3.基于上面的机制,action只有一个 ‘Set_Center_Filter’,用于判断按钮点击这个动作。

4.在reducer里改变isCenter,从而变化state,返回新的state

接下来是我自己一般的创建的流程

各组组件先创建,然后模拟父组件本身就有props数据,这一步和React无异。

components/App.js class App extends Component{ render{ const {dispatch , imgs } = this.props; return( "isCenter":"true",

"right" :"true"

}, { "img": "2.jpg", "h1": "Friendly", "h2": "Happy",

"isCenter":"true",

"right" :"true"

}]/> "isCenter":"true",

"right":"true" }, { "img": "2.jpg", "h1": "Friendly", "h2": "Happy",

"isCenter":"true",

"right":"true" }] /> ) } }

containers/ShowPic.js import React,{Component} from 'react'import MainI from './MainI'export default class ShowPic extends Component{ render{ return( {this.props.imgs.map((imgi , index)=> this.props.onCenterChange(index)} /> )} ) }}

containers/SetCenterFilter.js import React,{Component} from 'react'import CtrlI from './CtrlI'export default class SetCenterFilter extends Component{ render { return( {this.props.imgs.map((imgi , index) => this.props.onCenterClick(index)}/> )} ) }}

containers/CtrlI.js import React,{Component} from 'react'export default class CtrlI extends Component{ render{ var ctrlClassName = this.props.right == 'true'?'ctrl-i ctrl-i_right':'ctrl-i'; ctrlClassName += this.props.isCenter == 'true'?' ctrl-i_active':''; return( ) }}

containers/MainI.js import React,{Component} from 'react'export default class MainI extends Component{ render{ var mainClassName = this.props.right== 'true'?'main-i main-i_right':'main-i'; mainClassName += this.props.isCenter == 'true'?' main-i_active':''; return( {this.props.h1} {this.props.h2} ) }}

上面的步奏基本和React没有什么太大区别。

Action export const Set_Center_Filter = "Set_Center_Filter";export function setCenterFilter(index){ return {type : Set_Center_Filter , index}}

定义Action一定要对自己的场景熟悉,比如我的幻灯片只需要点击更换state,所以只有一个action改变事件。

Reducer /* * @param state 数组 * @return new Array * @功能 改变传进来的数组 isCenter="false" * */function reMapArr(state){ var rearr=; state.map((item)=>{ item.isCenter = "false" rearr.push(item); }) return rearr}function imgs(state =ImgDatas ,action){ console.log(state) //这里在未执行动作之前,便被初始化三次??? 麻烦知道的大神帮我讲解下 switch (action.type){ case Set_Center_Filter : return [ ...reMapArr(state.slice(0 , action.index)), Object.assign({} , state[action.index],{ isCenter : 'true' }), ...reMapArr(state.slice(action.index + 1)) ] default : return state }}const SliderApp = combineReducers({ imgs})export default SliderApp

这一段相当于核心步奏,将获得的index进行处理。然后将reducer通过combineReducers 合成store

思路:将采用分段形式,index前面一段将isCenter变为false,index自己将isCenter变为true,index后面isCenter变为false。

components/App.js 修改内容 class App extends Component{ render{ const {dispatch , imgs } = this.props; return( this.props.onIncrement(index)}/> ) }}function mapStateToProps(state) { return { imgs: state.imgs };}function mapDispatchToProps(dispatch) { return { onIncrement: (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( , document.getElementById('Pic_slider'))

最后一步就是用Provider让 App.js的connect知道从哪里获得store数据

以上就是这个React+Redux 实现幻灯片的思想,思想是自己的理解,如果有出错,还望大家指出,一起学习。