likes
comments
collection
share

(23)Redux 入门——⑤ actionTypes 的拆分 | React 基础理论实操

作者站长头像
站长
· 阅读数 3
转载请注明出处,未经同意,不可修改文章内容。

🔥🔥🔥“前端一万小时”两大明星专栏——“从零基础到轻松就业”、“前端面试刷题”,已于本月大改版,合二为一,干货满满,欢迎点击公众号菜单栏各模块了解。

涉及面试题:
1.React 中如何定义常量?
2. Redux 中常量的用途是什么?

编号:[react_23]

1 为什么要拆分 actionTypes

紧接上一篇代码(请自行打开编辑器查看代码),我们可以很明显地看到:

  • TodoList.js 文件中,需要不断地派发 action 。然后,每个 action 又有一个 type ,且对应一串“字符串”;

  • reducer.js 文件中,reducer 接收 actiontype 时,其“字符串”必须和 TodoList.jstype 对应的字符串“一模一样”!

这会带来什么问题呢?

我们在写代码的时候,偶尔会犯一些“笔误”。比如,在 TodoList.js 文件中,我们把 handleInputChange 方法里 type 对应的“字符串” "change_input_value" ,写成了 "change_inpvt_value"

import React, {Component} from "react";
import 'antd/dist/antd.css';

import { Input, Button, List } from 'antd';  

import store from "./store";

class TodoList extends Component {
  constructor(props) {
    super(props);
    
    this.state = store.getState();
    
    this.handleInputChange = this.handleInputChange.bind(this);  
    
    this.handleStoreChange = this.handleStoreChange.bind(this);  
    
    this.handleButtonClick = this.handleButtonClick.bind(this); 
    
    store.subscribe(this.handleStoreChange);  
    
  }
  
  render() {
    return (
      <div style={{marginTop: "10px", marginLeft: "10px"}}>
        <div>
          <Input 
            value={this.state.inputValue} 
            placeholder="todo info" 
            style={{width: "300px", marginRight: "10px"}} 
            
            onChange={this.handleInputChange}  
          /> 
          
          <Button type="primary" onClick={this.handleButtonClick}>提交</Button>  

          <List style={{marginTop: "10px", width: "300px"}} 

            bordered
            dataSource={this.state.list}
            renderItem={(item, index) => <List.Item onClick = {this.handleItemDelete.bind(this, index)}>{item}</List.Item>}
          /> 
          
        </div>
      </div>
    )
  }
  
  handleInputChange(e) { 
    const action = {
      type: "change_inpvt_value", // ❗️❗️❗️input 错写成 inpvt!
      
      value: e.target.value  
    }
    
    store.dispatch(action);  
  }

  handleStoreChange() { 
    
    this.setState(store.getState()); 
  }

  handleButtonClick() { 
    const action = {  
      type: "add_todo_item" 
    };
    
    store.dispatch(action); 
  }

  handleItemDelete(index) {  
    
    const action = {
      type: "delete_todo_item",  
      index 
    };
    
    store.dispatch(action);  
  } 

}

export default TodoList;

我们可能会想,既然单词拼错了,控制台肯定会报错吧。

返回页面查看(程序不运行,但控制台却没任何报错): (23)Redux 入门——⑤ actionTypes 的拆分 | React 基础理论实操

❗️这种“字符串”拼写的小错误,在没有“报错”的提示下,没准就会耗费你几个小时的时间找 bug。

2 拆分 actionTypes 的步骤

❓这种情况可以怎么解决呢? 答:

1️⃣在 store 目录下,新建一个 actionTypes.js 文件。 (23)Redux 入门——⑤ actionTypes 的拆分 | React 基础理论实操

2️⃣在 actionTypes.js 文件里,将之前 action 中 types 属性对应的“字符串”赋值给同名的“常量”,并把这个“常量”导出。

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

3️⃣接着,在 TodoList.jsreducer.js 文件中将上边定义的常量“引入”,并用“常量”替换所有的“字符串”。

TodoList.js 文件:

import React, {Component} from "react";
import 'antd/dist/antd.css';

import { Input, Button, List } from 'antd';  

import store from "./store";

// 3️⃣-①:引入“常量”;
import {CHANGE_INPUT_VALUE, ADD_TODO_ITEM, DELETE_TODO_ITEM} from "./store/actionTypes"; 

class TodoList extends Component {
  constructor(props) {
    super(props);
    
    this.state = store.getState();
    
    this.handleInputChange = this.handleInputChange.bind(this);  
    
    this.handleStoreChange = this.handleStoreChange.bind(this);  
    
    this.handleButtonClick = this.handleButtonClick.bind(this); 
    
    store.subscribe(this.handleStoreChange);  
    
  }
  
  render() {
    return (
      <div style={{marginTop: "10px", marginLeft: "10px"}}>
        <div>
          <Input 
            value={this.state.inputValue} 
            placeholder="todo info" 
            style={{width: "300px", marginRight: "10px"}} 
            
            onChange={this.handleInputChange}  
          /> 
          
          <Button type="primary" onClick={this.handleButtonClick}>提交</Button>  

          <List style={{marginTop: "10px", width: "300px"}} 

            bordered
            dataSource={this.state.list}
            renderItem={(item, index) => <List.Item onClick = {this.handleItemDelete.bind(this, index)}>{item}</List.Item>}
          />  
          
        </div>
      </div>
    )
  }
  
  // 3️⃣-②:用“常量”替换掉“字符串”;
  handleInputChange(e) { 
    const action = {
      type: CHANGE_INPUT_VALUE, 
      
      value: e.target.value  
    }
    
    store.dispatch(action);  
  }

  handleStoreChange() { 
    
    this.setState(store.getState()); 
  }

  handleButtonClick() { 
    const action = {  
      type: ADD_TODO_ITEM 
    };
    
    store.dispatch(action); 
  }

  handleItemDelete(index) { 
    
    const action = {
      type: DELETE_TODO_ITEM,  
      index 
    };
    
    store.dispatch(action); 
  } 

}

export default TodoList;

reducer.js 文件:

// 3️⃣-③:引入“常量”;
import {CHANGE_INPUT_VALUE, ADD_TODO_ITEM, DELETE_TODO_ITEM} from "./actionTypes";  

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

// 3️⃣-④:用“常量”替换掉“字符串”;
export default (state = defaultState, action) => { 
  
  if(action.type === CHANGE_INPUT_VALUE) {  
    
    const newState = JSON.parse(JSON.stringify(state)); 
  
    newState.inputValue = action.value;  
    
    return newState;  
  }
  
  if(action.type === ADD_TODO_ITEM) { 
    
    const newState = JSON.parse(JSON.stringify(state)); 
    newState.list.push(newState.inputValue); 
    newState.inputValue = ""; 
    
    return newState; 
  }
  
  if(action.type === DELETE_TODO_ITEM) {  
    
    const newState = JSON.parse(JSON.stringify(state)); 
    
    newState.list.splice(action.index, 1);  
    return newState; 
  }
  
  return state;
}

4️⃣查看下页面效果(正常运行): (23)Redux 入门——⑤ actionTypes 的拆分 | React 基础理论实操

❓5️⃣这样大费周章的好处是什么呢? 答: 在 TodoList.js 文件中,我们把 handleInputChange 方法里 type 对应的“常量CHANGE_INPUT_VALUE ,写成了 CHANGE_INPVT_VALUE

此时,程序就会给我们打印出清晰的“报错”信息: (23)Redux 入门——⑤ actionTypes 的拆分 | React 基础理论实操

如此一来,修改 bug 将变得特别简单!

祝好,qdywxs ♥ you!