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.按钮点击改变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(
            <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}
                      onChangeCenter={() => this.props.onCenterChange(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}
                           onClick={()=>this.props.onCenterClick(index)}/>
                )}
            </div>
        )

    }
}

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(
            <a className={ctrlClassName} onClick={this.props.onClick}>
                <img src={this.props.img} />
            </a>
        )
    }
}

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(
               <div className={mainClassName}>
                  <div className="caption">
                       <h2>{this.props.h1}</h2>
                       <h3>{this.props.h2}</h3>
                  </div>
                 <img src={this.props.img} />
               </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

/*
 * @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(
            <div className="slider">
                <ShowPic
                    imgs={this.props.imgs}/>

                <SetCenterFilter
                    imgs={this.props.imgs}
                    onCenterClick ={index => this.props.onIncrement(index)}/>
            </div>
        )
    }
}

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(
    <Provider store={store}>
        <App/>
    </Provider>,
    document.getElementById(‘Pic_slider‘)
)

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

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

以上的代码均可以在我的Github上找到,与君共勉。

时间: 2024-10-12 23:43:47

react + redux 实现幻灯片的相关文章

ReactJS React+Redux+Router+antDesign通用高效率开发模板,夜间模式为例

工作比较忙,一直没有时间总结下最近学习的一些东西,为了方便前端开发,我使用React+Redux+Router+antDesign总结了一个通用的模板,这个技术栈在前端开发者中是非常常见的. 总的来说,我这个工程十分便捷,对于初学者来说,可能包含到以下的一些知识点: 一.React-Router的使用 Router是为了方便管理组件的路径,它使用比较简单,一般定义如下就行,需要注意的是,react-router的版本有1.0-3.0,各个版本对应的API大致相似,但也有不同,我使用的是2.X的,

写了两篇文章,对于初学react+redux的人来说,很有好处

虽然官网的TodoList的例子写的很详细,但是都是一步到位,就是给你一个action,好家伙,全部都写好了,给你一个reducer,所有功能也是都写好了,但是我们这些小白怎么可能一下就消化那么多,那我们就来拆解,一步一步实现,试想我们开发程序也是一个一个功能区域实现,那么我们第一步就是先把整体结构构思出来,然后先把头部做出来,这样看是不是简单很多! 将持续更新react+redux 链接1:http://www.cnblogs.com/heigehe/articles/6237362.html

react+redux教程(五)异步、单一state树结构、componentWillReceiveProps

教程目录 react+redux教程(一)connect.applyMiddleware.thunk.webpackHotMiddleware react+redux教程(二)redux的单一状态树完全替代了react的状态机? react+redux教程(三)reduce().filter().map().some().every()....展开属性 react+redux教程(四)undo.devtools.router react+redux教程(五)异步.单一state树结构.compo

webpack+react+redux+es6

一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入门教程   redux middleware 详解   Redux研究 React 入门实例教程 webpack学习demo NPM 使用介绍 三.工程搭建 之前有写过 webpack+react+es6开发模式 ,文章里介绍了一些简单的配置,欢迎访问. 1.可以npm init, 创建一个新的工程

webpack+react+redux+es6开发模式

一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入门教程   redux middleware 详解   Redux研究 React 入门实例教程 webpack学习demo NPM 使用介绍 三.工程搭建 之前有写过 webpack+react+es6开发模式 ,文章里介绍了一些简单的配置,欢迎访问. 1.可以npm init, 创建一个新的工程

6周学习计划,攻克JavaScript难关(React/Redux/ES6 etc.)

6周学习计划,攻克JavaScript难关(React/Redux/ES6 etc.) 余博伦· 2 个月前 原文链接:A Study Plan To Cure JavaScript Fatigue 作者:Sacha Greif 和大家一样,最近我也看了Jose Aguinaga写的How it feels to learn JavaScript in 2016. 显然这篇文章击中了人们的痛处.它在Hacker News上排了不止一次第一.同样也是/r/javascript上最火的一篇,在Med

react+redux官方实例TODO从最简单的入门(6)-- 完结

通过实现了增-->删-->改-->查,对react结合redux的机制差不多已经了解,那么把剩下的功能一起完成吧 全选 1.声明状态,这个是全选状态 2.action约定 3.reducers,更新store 4.底层组件实现函数 5.上层组件数据传递 到这里全选的功能就实现了 显示action的数量和删除completed操作 整过过程一模一样 1. 2. 3. 4.(展示action数量的view) (删除completed的view) 放到Footer中 在上层父组件进行数据通信

react+redux教程(四)undo、devtools、router

上节课,我们介绍了一些es6的新语法:react+redux教程(三)reduce().filter().map().some().every()....展开属性 今天我们通过解读redux-undo的官方示例代码来学习,在redux中使用撤销功能.devtools功能.以及router. 例子 这个例子是个计数器程序,包含计数器.右边的redux开发工具.还有一个路由(不过只有“/”这一个地址). 源代码: https://github.com/lewis617/myReact/tree/ma

react+redux教程(三)reduce()、filter()、map()、some()、every()、...展开属性

reduce().filter().map().some().every()....展开属性   这些概念属于es5.es6中的语法,跟react+redux并没有什么联系,我们直接在https://developer.mozilla.org/en-US/ 这里可以搜索到相关api文档. 但是redux的官方示例中包含了这些语法的用法,我们正好可以在程序中学习这些语法.这里全部默认使用es6的写法. 例子 这是官方的todomvc的例子(https://github.com/lewis617/m