一步一步學(xué)習(xí) ReactNative + Redux(3.2:優(yōu)化,消除魔術(shù)字段)

寫在開始

記得本示例中的過濾條件有三個 All 、Undo 、Finish。
我們不止在一處使用了這些字符串,他們與我們的程序聯(lián)系非常緊密,耦合度太高,并且可能發(fā)展為泛濫。
如果以后有需求,要對條件進(jìn)行修改。我們需要一一找到,對其進(jìn)行修改。這無疑是一個繁瑣的過程,并且容易出錯。
所以,我們需要把它定義在一處,在其他地方進(jìn)行引用,這樣,如果修改需求不是特別大,我們只做一處修改,就能使全部生效。
這樣,我們將魔術(shù)字段消除了?。?!

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

消除魔術(shù)字段

1、定義變量

我們需要定義個變量,它是一個對象形式,有三個key ALL、UNDO、FINISH,對應(yīng)值為All、Undo、Finish,還要將其導(dǎo)出

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

/**
 * TODO 所有的過濾狀態(tài)
 * @type {Object}
 */
export const FILITER_KEYS = {
    ALL: 'All',
    UNDO: 'Undo',
    FINISH: 'Finish',
};

2、修改初始數(shù)據(jù)

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';

// 這是初始數(shù)據(jù)
const initState = {
    todos: [
        {id:1,title:'吃早飯',status:true},
        {id:2,title:'打籃球',status:false},
        {id:3,title:'修電腦',status:false},
    ],
    filter: FILITER_KEYS.ALL,                       // 修改初始數(shù)據(jù),使用變量的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);

運行項目,看看是否正常運行?是的,它在展示與操作上沒什么區(qū)別。

Paste_Image.png

我們對條件名稱進(jìn)行簡單修改 All => AllTodo、Undo => UnTodo、Finish => OverTodo
ReactReduxDemo/app/config/enum.js 文件,修改如下:

/**
 * TODO 所有的過濾狀態(tài)
 * @type {Object}
 */
export const FILITER_KEYS = {
    ALL: 'AllTodo',         // All => AllTodo
    UNDO: 'UnTodo',         // Undo => UnTodo
    FINISH: 'OverTodo',     // Finish => OverTodo
};

運行項目,看看是否過濾條件已經(jīng)修改了呢,點擊試試,沒啥問題。

Paste_Image.png
Paste_Image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容