react + redux 实现幻灯片

写在前面:

这一篇是我 使用scss + react + webpack + es6实现幻灯片 的进阶篇,效果请点我,将会使用上redux的基础用法,由于一开始没有理解好redux的用法,单纯看文档,实现Todo List效果。但却没有造成思路,当想改形成本身东西时,一脸懵逼,无从下手。后面动手整理思路,如下将会整理个人学习思路,若有出错,请各位指教。css

首先html

1.你有接触React 同时研究了 Redux,没有的话这里有不错的学习资源。 Redux中文文档 Redux 指导与Redux 式编程  Redux 简明教程 react

2.在火狐或者谷歌下载插件 React Devtools 这个将会原本来本的看到数据的传递,对于理解数据流动,必不可少webpack

3.这一篇是基于个人前一篇基础实现的,若是没看过,建议你熟悉一下。git

Redux 学习思路

下面的图是store的数据流动的方式es6

数据流程:1.经过store.dispatch 方法触发actiongithub

              2.相应的reducers更新stateweb

              3.调用subscribe方法注册执行回调npm

 

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.storereducers经过 createCtore提供

3. reducerscombineReducers 集合多个 reducer (todos , visibilityFilter)(整合到【1】里面的store)

4.以新增的todo为例,返回为 原数据加上新的数据,其被触发方式为dispatch(action)

5.容器组件的disptach(action) 经过connect将须要过滤后的state传给【1】中的<App/> 当作其props图2

Connect(App)的数据为stateAPP的数据为上层的state变成自身props

这就是整条数据链,至于剩下的组件,只须要拿到父组件的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

相关文章
相关标签/搜索