React 6 模块化React和Redux应用--Todo应用

本文介绍了两种常见的模块化应用组织方式:按角色组织和按功能组织,并详细解析了一个TODO应用的实现过程,从代码文件组织到状态树设计,再到视图组件搭建。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模块化应用要点

开始新项目之前,需考虑:

⓵ 代码文件的组织结构
⓶ 确定模块边界
⓷ store的状态树设计

案例介绍: TODO应用

代码文件的组织方式

1. 按角色组织

├── src
│── controller
│ ├── todoController.js
│ ├── filterController.js
├── models
│ ├── todoModel.js
│ ├── filterModel.js
├── node_modules
├── views
│ ├── todo.js
│ ├── todoItem.js
│ ├── filter.js
├── app.js

mvc划分为 controller、 Model、 View,代表三种模块角色,这种组织代码的方式为“按角色组织”–>衍生适合 redux 应用的构建中,则变为如下目录结构:

├── src
│── reducers
│ ├── todoReducer.js
│ ├── filterReducer.js
├── actions
│ ├── todoActions.js
│ ├── filterActions.js
├── node_modules
├── components //无状态傻瓜组件
│ ├── todoList.js
│ ├── todoItem.js
│ ├── filter.js
├── containers //内容组件
│ ├── todoListContainer.js
│ ├── todoItemContainer.js
│ ├── filterContainer.js
├── app.js

➪ but 并不是很好的划分方式, 按需求修改。

2. 按功能组织

todoList/
  actions.js
  actionTypes.js
  index.js
  reducer.js
  views/
    cornponent.js
    container.js
filter/
  actions.js
  actionTypes.js
  index.js
  reducer.js
  views/
    cornponent.js
    container.js

这个应用有2个功能: todoList 和 filter, 每个目录下都包含

➪ actionTypes.js 定义 action 类型;
➪ actions.js 定义 action 构造函数,决定了这个功能模块可以接受的动作;
➪ reducer.js 定义这个功能模块如何相应 actions.js 中定义的动作;
➪ views 目录,包含这个功能模块中所有的 React 组件,包括傻瓜组件和容器组件;
➪ index.js 这个文件把所有的角色导人,然后统一导出 。

redux应用建议使用此方式划分目录结构。

状态树的设计

状态树设计需遵循以下几个原则:

➪ 一个模块控制一个状态节点
➪ 避免冗余数据
➪ 树形结构扁平


TODO应用

1. 状态树设计:

{
    todos: [
    {
        text: 'First todo',
        completed: false,
        id: 0
    },
    {
        text: 'First todo',
        completed: false,
        id: 1
    }
    ],
    filter: 'all'
}

2. action 构造函数

actionTypes.js 和 acitons.js ;

todos/actionTypes.js : 定义 todos 支持的 action 类型。 添加, 状态更改, 删除三种 aciton 类型

export const ADD_TODO = 'TODO/ADD';
export const TOGGLE_TODO = 'TODO/TOGGLE';
export const REMOVE_TODO = 'TODO/REMOVE';

为避免命名冲突,加入特定唯一的前缀 TODO/FILTER/

todos/acitons.js : 构造函数:

import {ADD_TODO, TOGGLE_TODO, REMOVE_TODO} from './actionTypes';

let nextTodoId = 0;

export const addTodo = (text) => ({
  type: ADD_TODO,
  completed: false,
  id: nextTodoId ++,
  text: text
});

export const toggleTodo = (id) => ({
  type: TOGGLE_TODO,
  id: id
});

export const removeTodo = (id) => ({
  type: REMOVE_TODO,
  id: id
});

filter/actionTypes.js :

export const SET_FILTER = 'FILTER/SET';

filter/actions.js :

import {SET_FILTER} from './actionTypes';

export const setFilter = filterType => ({
  type: SET_FILTER,
  filter: filterType
});

3. 组合 reducer

每个功能目录下都有一个 reducer , 但是 createStore 只接受一个 reducer, => 在 store.js 中使用 combineReducers 方法将多个 reducer 组合起来。

store.js :

import {createStore, combineReducers} from 'redux';

import {reducer as todoReducer} from './todos';
import {reducer as filterReducer} from './filter';

const reducer = combineReducers({
  todos: todoReducer,
  filter: filterReducer
});

export default createStore(reducer);

todos/reducer.js :

import {ADD_TODO, TOGGLE_TODO, REMOVE_TODO} from './actionTypes';

export default (state = [], action) => {
  switch (action.type) {
    case ADD_TODO :
      return [
        {
          id: action.id,
          text: action.text,
          completed: false
        },
        ...state
      ];
    case TOGGLE_TODO :
      return state.map((todoItem) => {
        if (todoItem.id === action.id) {
          return {...todoItem, completed: !todoItem.completed};
        } else {
          return todoItem;
        }
      });
    case REMOVE_TODO :
      return state.filter((todoItem) => {
        return todoItem.id !== action.id;
      })
    default :
      return state;
  }
}

filter/reducer.js :

import {SET_FILTER} from './actionTypes';
import {FilterTypes} from '../constants';

export default (state = FilterTypes.ALL, action) => {
  switch(action.type) {
    case SET_FILTER : {
      return action.filter;
    }
    default:
      return state;
  }
}

4. 视图

todos/views/todo.js : 作为 todos 模块的view—>容器组件 包含添加 todo 组件和 todolist 组件
todos/views/addTodo.js : 添加 todo 组件
todos/views/todolist.js : todoList 组件, 容器组件—>包含 todoItem 组件
todos/views/todoItem.js : todoItem 组件

filter/views/filter.js : 作为 filter 模块的view—>容器组件 包含 link 筛选组件
filter/views/link.js : 筛选组件

5. 样式

各模块下的视图下的style.css


todo 示例:

这里写图片描述

代码仓库,喜欢请star♪(^∀^●)ノ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值