React + Redux实现计算案例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012987546/article/details/79992221

简单的实现计算的案例:
这里写图片描述

案例代码下载 地址

1.新建一个react项目

create-react-app react-redux-sample  //使用create-react-app脚手架创建一个react项目
cd react-redux-sample                //进入react-redux-sample项目根目录
npm start                            //运行项目

这里写图片描述

2.引入redux的库

npm install redux@3.7.2 --save

这里写图片描述

3.编写界面

这里写图片描述

Counter组件的实现:

import React, { Component } from 'react';
import CounterItem from './CounterItem'
const style = {
    width:'200px',
    backgroundColor:'skyblue',
    margin: '20px'
};
class Counter extends Component {
    render() {
        return (
            <div style={style}>
                <CounterItem id={0}></CounterItem>
                <CounterItem id={1}></CounterItem>
                <div>
                    合计:<span>20</span>
                </div>
            </div>
        );
    }
}
export default Counter;

CounterItem组件的实现:

import React, { Component } from 'react';

const style = {
    margin:'10px'
};

class CounterItem extends Component {
    constructor(props) {
        super(props);
        this.addCounter = this.addCounter.bind(this);
        this.removeCounter = this.removeCounter.bind(this);
    }
    addCounter(){
        alert('addCounter')
    }
    removeCounter(){
        alert('removeCounter')
    }
    render() {
        return (
            <div style={style}>
                <button onClick={this.addCounter}> + </button>
                    <span> 10 </span>
                <button onClick={this.removeCounter}> - </button>
            </div>
        );
    }
}
export default CounterItem;

执行的效果:

这里写图片描述

4.编写store

store.js文件

/*导入createStore函数来创建store对象*/
import { createStore } from 'redux';
/*导入reducer*/
import reducer from './reducer';

/*初始化状态树*/
const initValue=[
    {id:0,number:0},
    {id:1,number:0}
]
/*store与reducer关联*/
const store=createStore(reducer,initValue);

export  default store;

这里写图片描述

5.编写action

action.js文件

import * as ActionTypes from './actionTypes';
/*每一个action返回的是一个对象,对象必须包含type属性*/
export const addCounter=(id)=>({
        type:ActionTypes.addCounter,
        id:id,
})

export const removeCounter=(id)=>{
    return{
        type:ActionTypes.removeCounter,
        id:id,
    }
}

actiontypes.js文件

export const addCounter = 'addCounter';
export const removeCounter = 'removeCounter';

6.编写reducer

reducer.js文件

import * as ActionTypes from './actionTypes';
/*
 参数一:状态树
 state:[
       {id:0,number:0},
       {id:1,number:0}
 ]
 参数二:action 函数
     {
        type:ActionTypes.removeCounter,
        id:id,
     }
* */
export default (state,action )=>{

    const { id }=action;
    console.log(state , action.id , action.type);
    switch (action.type){
        //点击 +
        case ActionTypes.addCounter:
            //拷贝一个对象
            var s=Object.assign([],state);
            s[id].number+=1;
            return s;
        //点击 -
        case ActionTypes.removeCounter:
            //拷贝一个对象
            var s=Object.assign([],state);
            s[id].number-=1;
            return s;
        default:
            return state;
    }
}

7.在界面中引入store 对象

在顶级的index.js文件中引入store对象,并且将store对象传递给Counter的子组件

这里写图片描述

8.计算合计和更新合计

1.Counter组件拿到store对象的数据初始化状态

getOwnState() 函数是给Counter组件的状态机初始化

import React, { Component } from 'react';
import CounterItem from './CounterItem'

const style = {
    width:'200px',
    backgroundColor:'skyblue',
    margin: '20px'
};


class Counter extends Component {

    constructor(props){
        super(props);

        this.state = this.getOwnState();
        /**给getOwnState函数绑定this上下文*/
        this.getOwnState=this.getOwnState.bind(this);
    }

    getOwnState() {
        /*通过this.props.store对象获取状态树*/
        var state=this.props.store.getState();
        var sum=0;
        /*拿到状态树遍历计算合计*/
        state.forEach(function (item,index) {
            sum+=item.number;
        })
        /*返回新的状态机对象*/
        return {
            sum:sum,
        };
    }

    render() {
        /*获取状态机中的合计*/
        const sum =this.state.sum;
        return (
            <div style={style}>
                {/*又将唯一的store传给子组件*/}
                <CounterItem id={0} store={this.props.store}></CounterItem>
                <CounterItem id={1} store={this.props.store}></CounterItem>
                <div>
                    合计:<span>{sum}</span>
                </div>
            </div>
        );
    }

}

export default Counter;

2.Counter组件监听store中状态树的更新

//...
class Counter extends Component {
    constructor(props){
        //...
        this.onChange=this.onChange.bind(this);
    }
    getOwnState() {
        //...
    }
    render() {
        //...
    }

    /*如果store 发生了变化,将回调这个函数*/
    onChange() {
        //如果store 发生了变化,重新获取store中的值
        this.setState(this.getOwnState());
    }
    componentDidMount() {
        // 监听store 的变化
        this.props.store.subscribe(this.onChange);
    }
    componentWillUnmount() {
        //取消监听store 的变化
        this.props.store.unsubscribe(this.onChange);
    }
}

export default Counter;

9.CounterItem组件实现加和减

1.CounterItem组件拿到store对象的数据初始化状态

import React, { Component } from 'react';
import * as Actions  from '../action';

const style = {
    margin:'10px'
};

class CounterItem extends Component {
    constructor(props) {
        super(props);
        this.state=this.getOwnState();
        this.addCounter = this.addCounter.bind(this);
        this.removeCounter = this.removeCounter.bind(this);
        this.getOwnState = this.getOwnState.bind(this);

    }
    /**初始化状态机*/ 
    getOwnState(){
        /**获取父亲组件传递过来的store对象*/
        var {id,store}=this.props;
        /**获取状态树中对应的数据*/
        var oldNumber=store.getState()[id].number;
        /**返回一个对象给状态机*/
        return {
            number:oldNumber,
        }
    }

    addCounter(){

    }
    removeCounter(){

    }

    render() {
        var num=this.state.number;
        return (
            <div style={style}>
                <button onClick={this.addCounter}> + </button>
                    <span>{num}</span>
                <button onClick={this.removeCounter}> - </button>
            </div>
        );
    }
}

export default CounterItem;

2.点击加和减发送action

//...
class CounterItem extends Component {
    constructor(props) {
       //....
    }
    getOwnState(){
        //...
    }

    addCounter(){
        var{id,store}=this.props;
        //调用 store对象的dispatch来分发 + action
        store.dispatch( Actions.addCounter(id) );
    }
    removeCounter(){
        var{id,store}=this.props;
        //调用 store对象的dispatch来分发 - action
        store.dispatch( Actions.removeCounter(id) );
    }

    render() {
       //...
    }
}

export default CounterItem;

3.监听store中状态树的更新

//...
class CounterItem extends Component {
    constructor(props) {
        super(props);
        //...
        this.onChange = this.onChange.bind(this);
    }
    //...
    render() {
        //...
    }


    onChange() {
        //如果store 发生了变化,重新获取store中的值
        this.setState(this.getOwnState());
    }

    componentDidMount() {
        // 监听store 的变化
        this.props.store.subscribe(this.onChange);
    }

    componentWillUnmount() {
        //取消监听store 的变化
        this.props.store.unsubscribe(this.onChange);
    }
}

export default CounterItem;

最后执行的效果:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/u012987546/article/details/79992221
今日推荐