Redux之react的简单入门项目及其优化

注意:此Demo使用了react官方脚手架和antd

一:目的

在react中组件与组件之间的通信很麻烦,于是借用redux进行第三方的通信

通过把数据存储在store里,实现各个组件间快速通信

二:工作流程

or

注:store是一个联系和管理。具有如下职责

  • 维持应用的state

  • 提供getState()方法获取 state

  • 提供dispatch(action)方法更新 state;

  • 通过subscribe(listener)注册监听器;

  • 通过subscribe(listener)返回的函数注销监听器。

准备工作1:创建store(具体安装参考redux官网)

import {createStore} from 'redux';
import reducer from './reducer';
const store = createStore(
    reducer,
   
);
export default store;

准备工作2:创建reducer

const  defaultState={
    inputValue:'',
    list:[]
};

//reducer可以接收state,但是绝不能修改state

export default (state=defaultState,action)=>{
    
    return state;
}

流程1:传递action告诉store,store会自动转发给reducer

handleInputChange=(e)=>{

    //告诉store,输入的类型和输入框中的值
    const  action={
        type:'change_input_value',
        value: e.target.value,
    };
    //把action传给store
    store.dispatch(action);
    //store自动传给reducer
};

流程2:reducer接收信息,并返回给store一个newState

 

export default (state=defaultState,action)=>{
    //input
    if (action.type==='change_input_value'){
        const  newState=JSON.parse(JSON.stringify(state));//简单的深拷贝
        newState.inputValue=action.value;
        return newState;
    }

    
}

流程3:TodoList监听state的变化

    constructor(props){
        super(props);
        this.state=store.getState();
        //监听store里面的变化,只要一变化
        //只要store里面的数据发生改变,则立即执行subscribe函数里的函数
        store.subscribe(this.handleStoreChange)
    }
  handleStoreChange=()=>{
    this.setState(store.getState());
    // console.log('store change')
    // 感知store发生变化之后,从store里获取最新的数据,然后进行设置
  };

三:具体代码

1:结构图(使用了react官方脚手架)

2:index.js(入口文件)

import React from 'react';
import ReactDOM from 'react-dom';

import TodoList from './TodoList';


ReactDOM.render(<TodoList />, document.getElementById('root'));

3:TodoList.js

import React ,{Component}from 'react';
import 'antd/dist/antd.css'
import {Input,Button,List} from 'antd'
import store from './store/index';

class TodoList extends  Component{
    constructor(props){
        super(props);
        this.state=store.getState();//获取store里的所有关于state的数据
        //监听store里面的变化,只要一变化
        //只要store里面的数据发生改变,则立即执行subscribe函数里的函数
        store.subscribe(this.handleStoreChange)
    }
    render(){
        return(
            <div style={{margin:'10px',marginLeft:'10px'}}>
                <div>
                    <Input
                        value={this.state.inputValue}
                        placehoder="todo list "
                        style={{width:'300px'}}
                        onChange={this.handleInputChange}
                    />
                    <Button
                        type= "primary"
                        onClick={this.handleBtnClick}
                    >提交</Button>
                </div>
                <List
                    style={{marginTop:'10px',width:'300px'}}
                    bordered
                    dataSource={this.state.list}
                    renderItem={(item,index) => (<List.Item onClick={this.handleItemDelet} >{item}</List.Item>)}//这个这个参考antd官网
                />
            </div>
        )
    }
    handleInputChange=(e)=>{
        // console.log(e.target.value);//获取input的value值

        //告诉store,输入的类型和输入框中的值
        const  action={
            type:'change_input_value',
            value: e.target.value,
        };
        //把action传给store
        store.dispatch(action);
        //store自动传给reducer
    };


    //reducer返回newState之后,store传递newState给组件
    handleStoreChange=()=>{
        this.setState(store.getState());
        // console.log('store change')
        // 感知store发生变化之后,从store里获取最新的数据,然后进行设置
    };

    //提交按钮(又一次流程)
    handleBtnClick=()=>{
        const  action={
            type:'add_todo_item'
        };
        store.dispatch(action);
    };

    //点击删除
    handleItemDelet=(index)=>{
        const  action={
            type:'delete_todo_item',
            index:index,
        };
        store.dispatch(action);
    }
}

export default TodoList;

4:store下的index.js

import {createStore} from 'redux';
import reducer from './reducer';


//1-store是唯一的
//2-只有store才能改变自己的内容(state)
//3-reducer必须是纯函数
const store = createStore(
    reducer,
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
    // /如果安装了redeux devtools扩展这个工具(谷歌商店里下载),则在控制台里使用这个方法(为了调试redux)
);
export default store;

补充:可以下载谷歌插件方便查看store

效果:

 

5:store下的reducer.js

const  defaultState={
    inputValue:'',
    list:[]
};

//reducer可以接收state,但是绝不能修改state
// reducer必须是纯函数
//纯函数:给固定的输入,一定有固定的输出(不能有不固定的日期函数),不会有副作用(改变参数的值)
export default (state=defaultState,action)=>{
    //input
    if (action.type==='change_input_value'){
        const  newState=JSON.parse(JSON.stringify(state));//简单的深拷贝
        newState.inputValue=action.value;
        return newState;
    }

    //button
    if (action.type==="add_todo_item"){
        const  newState=JSON.parse(JSON.stringify(state));//把老数据拷贝一份
        newState.list.push(newState.inputValue);//在列表中新加输入框内容
        newState.inputValue='';//点击提交之后,输入框清空
        // console.log(newState);
        return newState;//返回给store
    }

    //点击删除
    if (action.type==='delete_todo_item'){
        const newState=JSON.parse(JSON.stringify(state));
        newState.list.splice(action.index,1);
        return newState;

    }
    return state;
}

 

四:效果预览

 

五:整体结构优化

1:优化的目标

    1.1:action的type由公共的actionTypes管理

 

const  action={
    // type:'add_todo_item'
    type:ADD_TODO_ITEM
};

    1.2:将action封装成对象,写在actionCreator.js文件里

 

//action封装之前
const  action={
    // type:'add_todo_item'
    type:ADD_TODO_ITEM
};
// action封装之后
const action=getAddItemActiom();
store.dispatch(action);
export  const getAddItemActiom=()=>({
    type:ADD_TODO_ITEM,
});

2:目录结构

3.index.js

 

import React from 'react';
import ReactDOM from 'react-dom';

import TodoList from './TodoList';


ReactDOM.render(<TodoList />, document.getElementById('root'));

 

4.TodoList.js

 

 

import React ,{Component}from 'react';
import 'antd/dist/antd.css'
import {Input,Button,List} from 'antd'
import store from './store/index';

import {getInputChangeAction,getAddItemActiom,getDeleteItemAction}from './store/actionCreator';//从封装的actionCreator解构出自定义的函数

class TodoList extends  Component{
    constructor(props){
        super(props);
        this.state=store.getState();
        //监听store里面的变化,只要一变化
        //只要store里面的数据发生改变,则立即执行subscribe函数里的函数
        store.subscribe(this.handleStoreChange)
    }
    render(){
        return(
            <div style={{margin:'10px',marginLeft:'10px'}}>
                <div>
                    <Input
                        value={this.state.inputValue}
                        placehoder="todo list "
                        style={{width:'300px'}}
                        onChange={this.handleInputChange}
                    />
                    <Button
                        type= "primary"
                        onClick={this.handleBtnClick}
                    >提交</Button>
                </div>
                <List
                    style={{marginTop:'10px',width:'300px'}}
                    bordered
                    dataSource={this.state.list}
                    renderItem={(item,index) => (<List.Item onClick={this.handleItemDelet} >{item}</List.Item>)}//这个这个参考antd官网
                />
            </div>
        )
    }
    handleInputChange=(e)=>{
        // console.log(e.target.value);//获取input的value值

        //告诉store,输入的类型和输入框中的值
        // const  action={
        //     // type:'change_input_value',
        //     type:CHANGE_INPUT_VALUE,//由公共常量代替,防止,字符串不一致
        //     value: e.target.value,
        // };
        const action=getInputChangeAction(e.target.value);
        //把action传给store
        store.dispatch(action);
        //store自动传给reducer
    };


    //reducer返回newState之后,store传递newState给组件
    handleStoreChange=()=>{
        this.setState(store.getState());
        // console.log('store change')
        // 感知store发生变化之后,从store里获取最新的数据,然后进行设置
    };

    //提交按钮(又一次流程)
    handleBtnClick=()=>{
        // //action封装之前
        // const  action={
        //     // type:'add_todo_item'
        //     type:ADD_TODO_ITEM
        // };
        // action封装之后
        const action=getAddItemActiom();
        store.dispatch(action);
    };

    //点击删除
    handleItemDelet=(index)=>{
        // const  action={
        //     // type:'delete_todo_item',
        //     type:DELETE_TODO_ITEM,
        //     index:index,
        // };
        // action封装之后
        const action=getDeleteItemAction(index);
        store.dispatch(action);
    }
}

export default TodoList;

 

5.store/index.js

 

 

import {createStore} from 'redux';
import reducer from './reducer';


//1-store是唯一的
//2-只有store才能改变自己的内容(state)
//3-reducer必须是纯函数
const store = createStore(
    reducer,
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
    // /如果安装了redeux devtools扩展这个工具(谷歌商店里下载),则在控制台里使用这个方法(为了调试redux)
);
export default store;

6.store/reducer.js

import {CHANGE_INPUT_VALUE,ADD_TODO_ITEM,DELETE_TODO_ITEM} from './actionTypes';//引入常量

const  defaultState={
    inputValue:'',
    list:[]
};

//reducer可以接收state,但是绝不能修改state
// reducer必须是纯函数
//纯函数:给固定的输入,一定有固定的输出(不能有不固定的日期函数),不会有副作用(改变参数的值)
export default (state=defaultState,action)=>{
    //input
    if (action.type===CHANGE_INPUT_VALUE){
        const  newState=JSON.parse(JSON.stringify(state));//简单的深拷贝
        newState.inputValue=action.value;
        return newState;
    }

    //button
    if (action.type===ADD_TODO_ITEM){
        const  newState=JSON.parse(JSON.stringify(state));//把老数据拷贝一份
        newState.list.push(newState.inputValue);//在列表中新加输入框内容
        newState.inputValue='';//点击提交之后,输入框清空
        // console.log(newState);
        return newState;//返回给store
    }

    //点击删除
    if (action.type===DELETE_TODO_ITEM){
        const newState=JSON.parse(JSON.stringify(state));
        newState.list.splice(action.index,1);
        return newState;

    }
    return state;
}

 

7.store/actionTypes.js

 

export const CHANGE_INPUT_VALUE='change_input_value';
export const ADD_TODO_ITEM='add_todo_item';
export const DELETE_TODO_ITEM='delete_todo_item';

8.store/actionCreator.js

//用actionCreator创建统一的action
import {CHANGE_INPUT_VALUE,ADD_TODO_ITEM,DELETE_TODO_ITEM} from './actionTypes';//引入常量

//为了封装  const  action={
//             // type:'add_todo_item'
//             type:ADD_TODO_ITEM
//         };
export  const getInputChangeAction=(value)=>({
    type:CHANGE_INPUT_VALUE,
    value:value,
});

export  const getAddItemActiom=()=>({
    type:ADD_TODO_ITEM,
});
export const getDeleteItemAction=(index)=>({
    type:DELETE_TODO_ITEM,
    index:index,
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值