美文网首页redux学习React Native实践ReactNative调研
一步一步学习 ReactNative + Redux(3.2:优

一步一步学习 ReactNative + Redux(3.2:优

作者: EyluWang | 来源:发表于2016-12-17 09:27 被阅读145次

    写在开始

    记得本示例中的过滤条件有三个 All 、Undo 、Finish。
    我们不止在一处使用了这些字符串,他们与我们的程序联系非常紧密,耦合度太高,并且可能发展为泛滥。
    如果以后有需求,要对条件进行修改。我们需要一一找到,对其进行修改。这无疑是一个繁琐的过程,并且容易出错。
    所以,我们需要把它定义在一处,在其他地方进行引用,这样,如果修改需求不是特别大,我们只做一处修改,就能使全部生效。
    这样,我们将魔术字段消除了!!!

    源码:https://github.com/eylu/web-lib/tree/master/ReactReduxDemo/app_step3.2

    消除魔术字段

    1、定义变量

    我们需要定义个变量,它是一个对象形式,有三个key ALLUNDOFINISH,对应值为AllUndoFinish,还要将其导出

    新建 ReactReduxDemo/app/config/enum.js 文件,如下:

    /**
     * TODO 所有的过滤状态
     * @type {Object}
     */
    export const FILITER_KEYS = {
        ALL: 'All',
        UNDO: 'Undo',
        FINISH: 'Finish',
    };
    

    2、修改初始数据

    ReactReduxDemo/app/index.js 文件,修改如下:

    import React, { Component } from 'react';
    import {
        View,
        StyleSheet,
    } from 'react-native';
    import { createStore } from 'redux';
    import { Provider } from 'react-redux';
    
    import { FILITER_KEYS } from './config/enum';        // 引用变量
    import reducers from './reducers/index';
    
    import HomeContainer from './containers/home.container';
    
    // 这是初始数据
    const initState = {
        todos: [
            {id:1,title:'吃早饭',status:true},
            {id:2,title:'打篮球',status:false},
            {id:3,title:'修电脑',status:false},
        ],
        filter: FILITER_KEYS.ALL,                       // 修改初始数据,使用变量的key
    };
    
    let store = createStore(reducers, initState);
    
    export default class RootWrapper extends Component{
        render(){
            return (
                <Provider store={store}>
                    <View style={styles.wrapper}>
                        <HomeContainer />
                    </View>
                </Provider>
            );
        }
    }
    
    const styles = StyleSheet.create({
        wrapper: {
            flex: 1,
            marginTop: 20,
        },
    });
    

    3、修改子组件TodoFilterComponent

    ReactReduxDemo/app/components/todo-filter.component.js 文件,修改如下:

    import React, { Component } from 'react';
    import {
        View,
        Text,
        TouchableOpacity,
        StyleSheet,
    } from 'react-native';
    
    import { FILITER_KEYS } from '../config/enum';               // 引用变量
    
    export default class TodoFilterComponent extends Component{
        constructor(props){
            super(props);
        }
    
        filterTodo(filter){
            this.props.filterTodo && this.props.filterTodo(filter);
        }
    
        renderFilter(filter){
            if(filter==this.props.filter){
                return (
                    <Text style={[styles.filter,styles.filterCurrent]}>{filter}</Text>
                );
            }
            return (
                <TouchableOpacity onPress={()=>{this.filterTodo(filter)}}>
                    <Text style={styles.filter}>{filter}</Text>
                </TouchableOpacity>
            );
        }
    
        render(){
            return (
                <View style={styles.wrapper}>
                    {this.renderFilter(FILITER_KEYS.ALL)}       // 使用变量的 key (注释会报错,请删除注释)
                    {this.renderFilter(FILITER_KEYS.UNDO)}      // 使用变量的 key (注释会报错,请删除注释)
                    {this.renderFilter(FILITER_KEYS.FINISH)}    // 使用变量的 key (注释会报错,请删除注释)
                </View>
            );
        }
    }
    
    
    const styles = StyleSheet.create({
        wrapper: {
            flexDirection: 'row',
            paddingLeft: 20,
            paddingTop: 20,
        },
        filter: {
            marginRight: 20,
            textDecorationLine: 'underline',
        },
        filterCurrent:{
            color: 'gray',
            textDecorationLine: 'none',
        },
    });
    

    4、修改容器组件HomeContainer

    import React, { Component } from 'react';
    import {
        View,
        Text
    } from 'react-native';
    import { connect } from 'react-redux';
    
    import { FILITER_KEYS } from '../config/enum';             // 引用变量
    import { changeTodoStatus, addNewTodo, filterTodoList } from '../actions/index';
    
    import TodoFormComponent from '../components/todo-form.component';
    import TodoListComponent from '../components/todo-list.component';
    import TodoFilterComponent from '../components/todo-filter.component';
    
    class HomeContainer extends Component{
        constructor(props){
            super(props);
        }
    
        addTodo(text){
            let { dispatch } = this.props;
            dispatch(addNewTodo(text));
        }
    
        toggleTodo(id){
            let { dispatch } = this.props;
            dispatch(changeTodoStatus(id));
        }
    
        filterTodo(filter){
            let { dispatch } = this.props;
            dispatch(filterTodoList(filter));
        }
    
        render(){
            return (
                <View>
                    <TodoFormComponent addTodo={(text)=>{this.addTodo(text)}} />
                    <TodoListComponent todoList={this.props.todoList} toggleTodo={(id)=>{this.toggleTodo(id)}} />
                    <TodoFilterComponent filter={this.props.currentFilter} filterTodo={(filter)=>{this.filterTodo(filter)}} />
                </View>
            );
        }
    }
    
    const getFilterTodos = (todos, filter) => {
      switch (filter) {
        case FILITER_KEYS.ALL:                             // 使用变量 key
          return todos;
        case FILITER_KEYS.UNDO:                            // 使用变量 key
          return todos.filter( todo => !todo.status);
        case FILITER_KEYS.FINISH:                          // 使用变量 key
          return todos.filter( todo => todo.status);
        default:
          throw new Error('Unknown filter: ' + filter);
      }
    }
    
    // 基于全局 state ,哪些 state 是我们想注入的 props
    function mapStateToProps(state){
        var list = getFilterTodos(state.todos, state.filter);
        return {
            todoList: list,
            currentFilter: state.filter,
        }
    }
    
    export default connect(mapStateToProps)(HomeContainer);
    

    运行项目,看看是否正常运行?是的,它在展示与操作上没什么区别。

    Paste_Image.png

    我们对条件名称进行简单修改 All => AllTodo、Undo => UnTodo、Finish => OverTodo
    ReactReduxDemo/app/config/enum.js 文件,修改如下:

    /**
     * TODO 所有的过滤状态
     * @type {Object}
     */
    export const FILITER_KEYS = {
        ALL: 'AllTodo',         // All => AllTodo
        UNDO: 'UnTodo',         // Undo => UnTodo
        FINISH: 'OverTodo',     // Finish => OverTodo
    };
    

    运行项目,看看是否过滤条件已经修改了呢,点击试试,没啥问题。

    Paste_Image.png Paste_Image.png

    相关文章

      网友评论

        本文标题:一步一步学习 ReactNative + Redux(3.2:优

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