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

复制代码
转载请注明出处,未经同意,不可修改文章内容。

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

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

编号:[react_23]

1 为什么要拆分 actionTypes

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

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

  • 在 reducer.js 文件中,reducer 接收 action 的 type 时,其"字符串"必须和 TodoList.js 里 type 对应的字符串"一模一样"!

这会带来什么问题呢?

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

jsx 复制代码
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;

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

返回页面查看(程序不运行,但控制台却没任何报错):

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

2 拆分 actionTypes 的步骤

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

答:

1️⃣在 store 目录下,新建一个 actionTypes.js 文件。

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

javascript 复制代码
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.js 和 reducer.js 文件中将上边定义的常量"引入",并用"常量"替换所有的"字符串"。

TodoList.js 文件:

javascript 复制代码
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 文件:

javascript 复制代码
// 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️⃣查看下页面效果(正常运行):

❓5️⃣这样大费周章的好处是什么呢?

答: 在 TodoList.js 文件中,我们把 handleInputChange 方法里 type 对应的"常量 " CHANGE_INPUT_VALUE ,写成了 CHANGE_INPVT_VALUE 。

此时,程序就会给我们打印出清晰的"报错"信息:

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

祝好,qdywxs ♥ you!

相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄3 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师3 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端