美文网首页
小白之利用todoList初步理解redux的store,act

小白之利用todoList初步理解redux的store,act

作者: 景元合 | 来源:发表于2019-08-15 10:37 被阅读0次

    前言

        刚学习redux,可惜脑子不够用,网上介绍的redux都有些高大上,晦涩难懂,今天就根据自己的理解,编写最简单的todolist,加深了解一下store,action,reducer。
    

    编写react的View页面

    为了方便ui显示,使用antd编写最简单ui页面,代码如下:

    import React, { Component } from 'react';
    import { Input,Button ,List} from 'antd';
    import 'antd/dist/antd.css';
    const data = [
      'Racing car sprays burning fuel into crowd.',
      'Japanese princess to wed commoner.',
      'Australian walks 100km after outback crash.',
      'Man charged over missing wedding girl.',
      'Los Angeles battles huge wildfires.',
    ];
    class AddName extends Component {
      constructor(props){
        super(props);
      }
    //渲染界面
      render() {
        return(
          <div style={{padding:'10px'}}>
            <div>
            <Input size="default" placeholder="todo list" style={{width:200,marginRight:'20px'}}></Input>
            <Button type="primary">提交</Button>
            </div>
            <div>
            <List
          size="small"
          style={{marginTop:'10px'}}
          bordered
          dataSource={data}
          renderItem={(item,index) => <List.Item>{item}</List.Item>}
        />
            </div>
            
          </div>
          
        )
      }
    }
    export default AddName;
    

    创建store

    store就好比图书馆,所有的数据都保存到store里面,并且store是唯一的。
    在项目下创建store文件夹,并新建index.js,代码如下:

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

    其中window.REDUX_DEVTOOLS_EXTENSION && window.REDUX_DEVTOOLS_EXTENSION()是用于启动chrome浏览器的redux DevTools工具,方便查看store数据。

    创建reduce

    reduce的作用好比图书馆计算机,reduce接收state与action2个参数,当检测到state有更新会将新的state传给store。

    import {CHANGE_INPUT_VALUE,ADD_TODO,DEL_TODO}from './actionTypes'
    const defaultState={
        value:'',
        list:[]
    }
    export default (state=defaultState,action)=>{
        switch(action.type){
            case CHANGE_INPUT_VALUE:
                {
                    let newState=Object.assign({},state,{
                        value:action.value
                    });
                    return newState;
                }
                break;
            case ADD_TODO:{
                let newTodoList=Object.assign({},state,action);
                newTodoList.list.push(newTodoList.value);
                newTodoList.value='';
                return newTodoList;
            }
            break;
            case DEL_TODO:{
                let newTodoList=Object.assign({},state,action);
                newTodoList.list.splice(action.index,1);
                return newTodoList;
            }  
            break;  
            default:
                return state 
        }
    }
    

    以上代码引入actionTypes.js其目的是为了方便统一管理action的type,以防代码写错不易检测,代码主要如下:

    export const CHANGE_INPUT_VALUE = 'change_input_value';
    export const ADD_TODO='add_todo';
    export const DEL_TODO='del_todo'
    

    创建action.js

    action好比我们告诉图书管理员我要借书这个动作,主要是把数据从应用传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说你会通过 store.dispatch() 将 action 传到 store。
    代码主要如下:

    import {CHANGE_INPUT_VALUE,ADD_TODO,DEL_TODO}from './actionTypes'
    export const getInputchangeAction=(value)=>({
        type:CHANGE_INPUT_VALUE,
        value:value
    })
    export const getSubmitAction=()=>({
        type:ADD_TODO
    })
    export const getDelItemAction=(index)=>({
        type:DEL_TODO,
        index:index
    })
    

    Action 本质上是 JavaScript 普通对象。我们约定,action 内必须使用一个字符串类型的 type 字段来表示将要执行的动作。多数情况下,type 会被定义成字符串常量。当应用规模越来越大时,建议使用单独的模块或文件来存放 action。
    Action还可以传递其他自定义参数,不过我们建议我们应该尽量减少在 action 中传递的数据。

    最后修改app.js,

    import React, { Component } from 'react';
    import store from './store'
    import {getInputchangeAction,getSubmitAction,getDelItemAction} from './store/action'
    import { Input,Button ,List} from 'antd';
    import 'antd/dist/antd.css';
    class AddName extends Component {
      constructor(props){
        super(props);
        this.state=store.getState();
        store.subscribe(()=>{
         this.handleStorechange();
        })
      }
      handleStorechange=()=>{
        this.setState(store.getState());
      }
      handleInputchange=(e)=>{
        const action=getInputchangeAction(e.target.value)
        store.dispatch(action);
      }
      handleSubmit=()=>{
        const action=getSubmitAction();
        store.dispatch(action);
      }
      delItem=(index)=>{
        const action=getDelItemAction(index);
        store.dispatch(action);
      }
    //渲染界面
      render() {
        return(
          <div>
            <div>
            <Input value={this.state.value} onChange={this.handleInputchange} size="default" placeholder="todo list" style={{width:200,marginRight:'20px'}}></Input>
            <Button type="primary" onClick={this.handleSubmit}>提交</Button>
            </div>
            <div>
            <List
          size="small"
          style={{marginTop:'10px'}}
          bordered
          dataSource={this.state.list}
          renderItem={(item,index) => <List.Item onClick={this.delItem.bind(this,index)}>{item}</List.Item>}
        />
            </div>
            
          </div>
          
        )
      }
    }
    export default AddName;
    

    以上代码通过引入action通过store.dispatch实现view页面与store的通信,store自动触发reduce,并且在页面注册监听器,数据改变后通知触发订阅,从而实现页面数据实时更新。

    总结

    我也是刚学redux的皮毛,不太会表达,通过这个todoList的demo,算是基本了解了redux的基本用法,大家可以和我一样牢记下面这个图,可以很好地理解redux。


    48312444-8ff2e100-e5e9-11e8-844a-48ffd9933265.png

    相关文章

      网友评论

          本文标题:小白之利用todoList初步理解redux的store,act

          本文链接:https://www.haomeiwen.com/subject/avlnjctx.html