• redux


    最近接盘了一个react项目,对于没有接触过react项目的我,慌的不行。花费了一天的时间来看了react.js的文档后,开始了写react项目。在项目的过程中,传递数据真的太痛苦了,特别对于深层次组件,例如我写的一个酷我播放器页面,简直惨不忍睹,一个组件几十个数据,方法的传入,显得项目不可直视,为了赶进度也没有管,现在告一段落后,来学习了一下redux状态管理!分享写经验!

    git地址:https://gitee.com/xieyong1234/redux-study.git

    对于官网的描述,我就不再复述,直接先上代码结构,我对redux的结构进行的拆分。

    redux的结构无外乎就是store,state,action, reducer来组成整个数据的修改与传递。简单的来描述redux的执行过程:

    1:组件出发action来告知store你所要做的事情,

    2:store通过reducer来处理对应的事件,reducer返回新的完整的state对象;

    3:store接受reducer返回的对象更新state;

    4:store将新的值传递给组件完成视图的更新

    先来说下redux的执行细节及对应的api:

      1.组件通过store的dispatch方法来传递action,store.dispatch(action);

      2.reducer根据action来判断执行操作,返回完整的新对象,

      3.store通过subscribe方法来监听state的变化,通知页面更新。store.subscribe(function(){});

      4.更新函数通过setState()来出发视图刷新,页面的数据通过store.getState()来获取整个state

    现在来贴上每个对应文件的代码,便于理解

      入口文件:

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import * as serviceWorker from './serviceWorker';
    ReactDOM.render(
        <App />,
        document.getElementById('root')
    );
    
    serviceWorker.unregister();

      组件文件:

    import React,{ Component } from 'react';
    import "antd/dist/antd.css";//antd的ui
    import { Input, Button, List, Checkbox } from 'antd';
    //引入自己定义好的action创建函数(为了拆分,便于维护) import { changeInput, add_todo_item, delete_todo_item, check_box_handler, census_check_num, delete_completed }
    from './store/actionCreators'; import store from './store/'; //引入store class App extends Component { constructor(props){ super(props); this.state = store.getState();//将store的state this.handleInputChange = this.handleInputChange.bind(this); this.updateState = this.updateState.bind(this); this.addTodoItem = this.addTodoItem.bind(this); this.deleteChecked = this.deleteChecked.bind(this); store.subscribe(this.updateState)//监听store里state的更新 } updateState(){ this.setState(store.getState());//出发视图更新 } handleInputChange(e){ //input输入框的数据变化 store.dispatch(changeInput(e.target.value));//调用dispatch方法,传入对应的action来改变state } addTodoItem(){ //添加 store.dispatch(add_todo_item()); } deleteTodoItem(index){ //删除一项todo store.dispatch(delete_todo_item(index)); this.censucNum() } checkboxHandler(index){ //选中checkbox store.dispatch(check_box_handler(index)); this.censucNum(); } censucNum(){ //统计选中数量 store.dispatch(census_check_num()); } deleteChecked(){ //删除所有选中 store.dispatch(delete_completed()); this.censucNum(); } render() { const { value, list, activeNum } = this.state; return <div style={{maringTop:'10px',marginLeft:'10px'}}> <Input value={value} onChange={this.handleInputChange} placeholder="todo info" style={{'300px',marginRight:'10px'}}/> <Button type="primary" onClick={this.addTodoItem}>submit</Button> <List style={{'300px',marginTop:'10px'}} bordered dataSource={list} renderItem={(item,index) => (<List.Item style={{position:'relative'}}><Checkbox checked={item.isCompleted} onChange={this.checkboxHandler.bind(this,index)} style={{marginRight:'10px'}}></Checkbox><div style={item.isCompleted ? {textDecoration:'line-through',color:'#ccc'} : {}}>{item.name}</div><div onClick={this.deleteTodoItem.bind(this,index)} style={{position:'absolute',right:'10px',top:'50%',transform:'translateY(-50%)',cursor:'pointer','20px',heigth:'20px',border:'1px solid #ccc',borderRadius:'50%',textAlign:'center',lineHeight:'20px'}}>X</div></List.Item>)} /> <div style={{'300px',height:'50px',display:'flex',justifyContent:'space-around',alignItems:'center',border:'1px solid #ccc',marginTop:'10px',borderRadius:'3px'}}> <span>{activeNum}item</span> <span onClick={this.deleteChecked} style={{cursor:'pointer'}}>delete completed</span> </div> </div> } } export default App;

      store文件:index.js

    import { createStore } from 'redux'; //引入redux的函数,创建store
    import reducer from './reducers'; //引入写好的reducer,注入store
    const store = createStore(
        reducer,
        window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()//应用于谷歌的redux'插件
    );
    export default store;

      action的type类型:actionTypes.js

    export const CAHNGE_INPUT_VALUE = 'change_input_value';
    export const ADD_TODO_ITEM = 'add_todo_item';
    export const DELETE_TODO_ITEM = 'delete_todo_item';
    export const CHECK_BOX_HANDLER = 'check_box_helder';
    export const CENSUS_CHECK_NUM = 'census_check_num';
    export const DELETE_COMPLETED = 'delete_completed';

      action的创建函数:cactionCreators.js

    import { CAHNGE_INPUT_VALUE, ADD_TODO_ITEM, DELETE_TODO_ITEM, CHECK_BOX_HANDLER, CENSUS_CHECK_NUM, DELETE_COMPLETED } from './actionTypes';
    export const changeInput = (value) => { //input框的创建函数,传入输入值,返回对应的action
        return {
            type: CAHNGE_INPUT_VALUE,
            value
        }
    }
    export const add_todo_item = () => {
        return {
            type:ADD_TODO_ITEM
        }
    }
    export const delete_todo_item = (index) => {
        return {
            type:DELETE_TODO_ITEM,
            index
        }
    }
    export const check_box_handler = (index) => {
        return {
            type:CHECK_BOX_HANDLER,
            index
        }
    }
    export const census_check_num = () => {
        return {
            type:CENSUS_CHECK_NUM
        }
    }
    export const delete_completed = () => {
        return {
            type:DELETE_COMPLETED
        }
    }

      reducer文件:reducers.js

      

    import { CAHNGE_INPUT_VALUE, ADD_TODO_ITEM, DELETE_TODO_ITEM, CHECK_BOX_HANDLER, CENSUS_CHECK_NUM, DELETE_COMPLETED
     } from './actionTypes';
    const initState = { //state的默认值
        value:'',
        list:[
            {
                name:'1',
                isCompleted:false
            }
        ],
        activeNum:0
    }
    export default (state=initState,action) => { //切记,reducer是一个纯函数,即输入条件相同,则输入一定相同,且不能有负面的影响;reducer中不能改变state
        let newState;
        switch(action.type){
            case CAHNGE_INPUT_VALUE:
                return Object.assign({},state,{value:action.value});
            case ADD_TODO_ITEM:
                newState = JSON.parse(JSON.stringify(state));
                if(newState.value.trim() === '') return newState;
                newState.list.push({name:newState.value,isCompleted:false});
                newState.value = '';
                return newState;
            case DELETE_TODO_ITEM:
                newState = JSON.parse(JSON.stringify(state));
                newState.list.splice(action.index,1);
                return newState;
            case CHECK_BOX_HANDLER:
                newState = JSON.parse(JSON.stringify(state));
                newState.list[action.index].isCompleted = !newState.list[action.index].isCompleted;
                return newState;
            case CENSUS_CHECK_NUM:
                newState = JSON.parse(JSON.stringify(state));
                let num=0;
                newState.list.forEach(element => {
                    if(element.isCompleted) num++
                });
                return Object.assign({},state,{activeNum:num});
            case DELETE_COMPLETED:
                newState = JSON.parse(JSON.stringify(state));
                for(var i = newState.list.length-1;i>=0;i-- ){
                    var item = newState.list[i]
                    if(item.isCompleted){
                        newState.list.splice(i,1)
                    }
                }
                return newState;
            default:
                return state
        }
    }

    至此,一个简单的redux项目就已经完成,效果如图:

      redux和react并没有直接的关联,他也可以用在jq,js, ang中。现在初步的了解了redux后,可能你也发现他用起来不怎么好用,需要手动更新视图等,现在提供了一个react-redux来配合redux完成一个完整的状态管理机制。且结构更加清晰,组件化更极致。react被区分为视图ui组件和容器组件,ui展示组件只负责静态的视图层面,所有的数据,方法操作全部都在容器组件中完成,通过react-redux提供的几个方法,完成更好的实现方式!我将在下一次更新除react-redux的用法,同一个例子,到时候可以自行看到区别和用法!只要静下心,其实也都很容易理解,虽然感觉react非常复杂,难用,由于jsx的应用,使得项目写起来更费时费力,但他的结构,组件化更清晰!期待下次的更新

  • 相关阅读:
    [Swift]LeetCode773. 滑动谜题 | Sliding Puzzle
    [Swift]LeetCode771. 宝石与石头 | Jewels and Stones
    [Swift]LeetCode770. 基本计算器 IV | Basic Calculator IV
    [Swift]LeetCode769. 最多能完成排序的块 | Max Chunks To Make Sorted
    [Swift]LeetCode768. 最多能完成排序的块 II | Max Chunks To Make Sorted II
    转 玩转Bash变量
    转 shell脚本学习指南
    转: 两个 Shell 网站: explainshell 和 shellcheck
    转 BAT CMD 批处理文件脚本总结(中文)
    转 windows 下 Oracle 导出表结构
  • 原文地址:https://www.cnblogs.com/xieyong25/p/10832669.html
Copyright © 2020-2023  润新知