一个最最简单的React-Redux使用例子

Redux 是 JavaScript 状态容器,提供可预测化的状态管理。

官方文档:http://cn.redux.js.org//index.html#

要点(官方):应用中所有的 state 都以一个对象树的形式储存在一个单一的 store 中。

惟一改变 state 的办法是触发 action,一个描述发生什么的对象。
为了描述 action 如何改变 state 树,你需要编写 reducers

示例:


 点击Add Age 年龄加一,点击Sub Age 年龄减一, 第三行输入名字,点击提交,第一行名字改变。

示例非常简单,没有涉及到redux中的所有功能,只是一个redux的使用流程。

目录结构为:


 

步骤: 1.配置webpack。

            2.编写网页显示信息,在container中创建组件。

    (1)根组件index.js,是所有其它组件的父组件

import React, { Component, PropTypes } from 'react'
import Name from './name.js'
import Age from './age.js'
import Form from './form.js'

var App = React.createClass({
    render() {
        return (
            <div>
                <Name />
                <Age />
                <Form />
            </div>
        )
    }
});

export default App;

      (2)Name组件,输出为My name is XXX 。 其中XXX为变化的状态

               使用connect把整个的State转换为props传递给Name组件

               其中用到了dispatch。dispatch属于react-redux,但是在有效组件中使用this.props.dispatch就能获取。作用是可以分发action,从而触发reducer改变State。

import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'

var Name = React.createClass({
    render() {
        const { name } = this.props;
        return (
            <div>
                My name is <i>{name}</i> .
            </div>
        );
    }
});

Name.PropType = {
    name: PropTypes.string.isRequired
};

function select(state) {
    return {
        name: state.inputInfo.name
    }
}

export default connect(select)(Name);

       (3)Age组件,输出 I am X years old this year. 并提供年龄更改的按钮。

                和Name一样,用connect连接。

import React, { Component, PropTypes } from 'react'
import { clickAdd, clickSub } from '../action/changeAge.js'
import { connect } from 'react-redux'

var Age = React.createClass({
    render() {
        const { age } = this.props;
        return (
            <div>
                I am {age} years old this year .
                <button onClick={this.clickAdd}>Add Age</button>
                <button onClick={this.clickSub}>Sub Age</button>
            </div>
        );
    },

    clickSub(event) {
        this.props.dispatch(clickSub());
    },

    clickAdd(event) {
        this.props.dispatch(clickAdd());
    }

});


Age.PropTypes = {
    age: PropTypes.string.isRequired
};

function select(state) {
    return {
        age: state.changeAge
    }
}

export default connect(select)(Age);

     (4)Form组件,提供输入框和确定按钮。提供把输入的字符传入到Name组件中的功能

import React, { Component, PropTypes } from 'react'
import { inputInfo } from '../action/inputInfo.js'
import { connect } from 'react-redux'


var Form = React.createClass({
    render() {
        return (
            <div>
                    <input type="text" placeholder="name" id="nameInput" />
                    <button onClick={ this.clickSubmit }>提交</button>
            </div>
        );
    },

    clickSubmit(event) {
        var name = document.getElementById('nameInput').value;
        console.log(name);
        this.props.dispatch(inputInfo(name));
    }

});

export default connect()(Form);

       

         3, 编写Action目录下的内容。根据创建的组件代码可知,需要改变状态的有三个:年龄加一,年龄减一,更改姓名。年龄加一和减一改变的都是Age中属性。所有创建两个文件changeAge.js和inputInfo.js,分别代表年龄更改和输入姓名。代码如下:

//changeAge
export const CLICK_ADD = 'CLICK_ADD';
export const CLICK_SUB = 'CLICK_SUB';

export function clickAdd() {
    return {
        type: CLICK_ADD
    }
}

export function clickSub() {
    return {
        type: CLICK_SUB
    }
}

 

//inputInfo
export const INPUT_INFO = "INPUT_INFO";

export function inputInfo(name) {
    return {
        type: INPUT_INFO,
        name
    }
}

     

          4,编写reducer。指明发生某个Action之后需要做的事。同样按照action目录分为两个文件,代码如下:

//changeAge.js
import { CLICK_ADD, CLICK_SUB } from '../action/changeAge.js'

function initialState() {
    return 20;
}

function changeAge(state=initialState(), action) {
    var value;
    switch(action.type) {
        case CLICK_ADD: {
            value = state + 1;
            return value

        }
        case CLICK_SUB: {
            value = state - 1;
            return value

        }
        default :{
            return state
        }
    }
}

export default changeAge;

 

//inputInfo.js
import { INPUT_INFO } from '../action/inputInfo.js'

function initialState() {
    return {
        name: "LiMing"
    }
}

function inputInfo(state=initialState(), action) {
    switch (action.type) {
        case INPUT_INFO: {
            return {
                name: action.name
            }
        }
        default :
            return state;
    }
}

export default inputInfo;

     

           创建好两个文件,再创建一个index文件,建立一个rootReducer,用来把刚刚创建的两个Reducer合并为一个。其中用到了combineReducers管理这两个Reducer。

import changeAge from './changeAge.js'
import inputInfo from './inputInfo.js'
import { combineReducers } from 'redux'

const rootReducer = combineReducers(
    {
        changeAge,
        inputInfo
    }
);

export default rootReducer;

     

           5,创建store。每个程序只能有一个store,可以根据已有的Reducer来创建store

import { createStore } from 'redux'
import rootReducer from '../reducer/index.js'

const store = createStore(rootReducer);

export default store;

     

          6,编写最外部的index.js,引入store。其中用到了Provider,可以保存store给子组件中的connect使用。

import App from './container/index.js'
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import store from './store/index.js'


render(
    <div>
        <Provider store={store} >
            <App />
        </Provider>
    </div>,
    document.getElementById('content')
);

    OK!!!

猜你喜欢

转载自2914905399.iteye.com/blog/2315938