React Clean Architecture React Clean Architecture 涵盖 - 应用程序 - 基础设施 - 演示 -

2025-05-27

React Clean Architecture

React Clean Architecture 涵盖 -

应用 -

基础设施 -

推介会 -

各位开发者们,大家好!我们许多人在 React 开发中使用各种设计模式,以使 React 应用更简洁、更易理解、更结构化。但我们仍然面临编码规范的问题,我们修改了一个地方,另一个地方就崩溃了。有解决办法吗?有的,试试 React 简洁架构吧!

快速亮点- React 简洁架构 - 让你的代码更加结构化、简洁,任何人都可以轻松接管你的代码并开始与你合作。接下来我们继续。它涵盖了所有 API、状态管理(Redux、Redux Saga)、Storybook、实用程序、组件/容器,并且你可以在定义的结构层次结构中添加更多相关功能。

React Clean Architecture 涵盖 -

react-clean-architecture
├── android
├── ios
├── src
│   ├── application
│   │   ├── common
│   │   ├── filters
│   │   ├── logger
│   │   ├── models
│   │   ├── persist
│   │   ├── plugins
│   │   ├── store
│   ├── infrastructure
│   │   ├── api(services)
│   │   ├── components (common components)
│   ├── presentation
│   │   ├── container
│   │   ├── component
├── index.js
├── package.json
└── README.md
Enter fullscreen mode Exit fullscreen mode

应用 -

应用程序目录包含状态管理和常用实用程序函数及常量。对于状态管理,我使用了 Redux Rematch,您也可以使用 Redux、Redux Saga 和MobX状态管理。对于常用功能,我使用了字体、颜色、全局常量和常用函数。

让我们检查一下 Rematch 的一些部分并了解它的作用和含义。

店铺 -

# Store/index.js 

import { init } from '@rematch/core';
import logger from 'redux-logger';

import * as models from '../models';
import { loadingPlugin } from '../plugins';
import { persistPlugin } from '../persist';

export default init({
  models,
  plugins: [loadingPlugin, persistPlugin],
  redux: {
    middlewares: [logger],
  },
});
Enter fullscreen mode Exit fullscreen mode

在这里,我初始化 Redux Store,要初始化 Redux Store 我们需要模型、插件、中间件(可选)。

插件 -

PlugIns 本身意味着为 Redux Store 增添一些价值。这里我们使用了 Loading PlugIns,这意味着它会在 API 获取数据时显示加载指示器。因此,我们可以向用户显示 Loader,一旦数据获取完成,Loading 插件就会更新加载状态,并基于此隐藏组件中的 Loader。

import createLoadingPlugin from '@rematch/loading';

export const loadingPlugin = createLoadingPlugin({
  whitelist: ['ToDo/fetchTasks'],
});
Enter fullscreen mode Exit fullscreen mode

持续存在 -

Persist 本身就是持久化某些东西,在这里,它将持久化到 Rematch Store。创建持久化存储需要几个参数:键、白名单(模型 - 保存在持久化存储中)、黑名单(模型 - 不保存在持久化存储中)、版本 - 升级应用程序时的帮助信息、存储 - AsyncStorage(将持久化存储存储在 AsyncStorage 中)、转换 - 包含 - 持久化存储时应用的过滤器。

import AsyncStorage from '@react-native-community/async-storage';
import createRematchPersist from '@rematch/persist';
import { AllFilters } from '../filters';

export const persistPlugin = createRematchPersist({
  key: 'root',
  whitelist: ['ToDo'],
  version: 1,
  storage: AsyncStorage,
  transforms: AllFilters,
});
Enter fullscreen mode Exit fullscreen mode

模型 -

模型将包含状态、Reducer、效果(动作)。

import { List } from '../../infrastructure/api/api';
export const ToDo = {
  state: {
    arrTasks: [],
    arrAPITasks: [],
    totalTasks: 3,
  },
  reducers: {
    setTasks(state, payload) {
      return {
        ...state,
        arrTasks: payload,
      };
    },
    setAPITasks(state, payload) {
      return {
        ...state,
        arrAPITasks: payload,
      };
    },
    clear() {
      return {
        arrBeneficiary: [],
      };
    },
  },
  effects: (dispatch) => ({
    async fetchTasks() {
      try {
        dispatch.ToDo.setTasks([
            {
                taskID: 1,
                taskName: 'Task #1',
            }
        ]);
      } catch (error) {
      }
    },
    async fetchTasksFromServer() {
      try {
        const response = await List.getListData().toPromise();
        dispatch.ToDo.setAPITasks(response);
      } catch (error) {
      }
    },
  }),
};
Enter fullscreen mode Exit fullscreen mode

过滤器 -

import { createBlacklistFilter } from 'redux-persist-transform-filter';

const toDoFilter = createBlacklistFilter('ToDo', ['totalTasks']);

export const AllFilters = [toDoFilter];
Enter fullscreen mode Exit fullscreen mode

常见的 -

在这里,您可以根据自定义解决方案定义全局常量、通用文件 - 字体、字体大小、设备规格、颜色等等。

exports.globalVars = {
    userSalt: 'TOHV7eOQRAXmbe433BilgtJeCkugs1rgvZ',
    currentCountryCode: '',
};
export const BaseURL = "https://jsonplaceholder.typicode.com/";
export const TaskList = 'todos/';
export const apiVersion = 'events/';
export const Authsecret = '';
export const timeoutDuration = 30000;

// Error Messages
export const errorEncountered = 'Error was encountered processing this request';
export const timeoutMessage =
    "We are unable to fetch data at this time, kindly check your internet connection and we'll reconnect you.";

Enter fullscreen mode Exit fullscreen mode

阅读最佳 JavaScript 编码实践

基础设施 -

基础设施包含 API(服务)文件、API 处理程序、通用组件(如加载器、通用文本字段、按钮等)。在这里,我使用了 AXIOS,您可以使用 JavaScript Fetch 并在此处创建您的 API 包装器类。

让我们检查一下基础设施的一些部分,并了解它的作用和含义。

了解更多关于 -零捆绑包大小 - React 服务器组件

API(服务) -

# api/api/List.js

import APIHandler from '../APIHandler';
import * as Globals from '../../../application/common/Globals';

export default {
  getListData: () => APIHandler.get(Globals.TaskList),
};
Enter fullscreen mode Exit fullscreen mode
# api/APIHandler.js

import { Alert } from 'react-native';
import { Observable, throwError, from } from 'rxjs';
import {
  mergeMap, retryWhen, take, delay, catchError, map,
} from 'rxjs/operators';
import axios, { AxiosPromise } from 'axios';
import * as Globals from '../../application/common/Globals';

async function handleRequest(req) {
  const ts = new Date().getTime();
  req.headers.Accept = 'application/json';
  req.headers.timestamp = ts;
  return req;
}

export default {
  post: (url: string, data: any, options?: any) => processApiRequest(
    axios.post(
      options && options.fullPath ? url : Globals.BaseURL + url,
      data,
      { timeout: Globals.timeoutDuration },
      options && { headers: options },
    ),
  ),
  get: (url: string, options?: any, data?: any) => {
    data = data ? (data instanceof Object && !Object.keys(data).length ? null : data) : null;
    const config = data
      ? { headers: options, data, timeout: Globals.timeoutDuration }
      : { headers: options, data: '', timeout: Globals.timeoutDuration };
    return processApiRequest(
      axios.get(options && options.fullPath ? url : Globals.BaseURL + url, config),
    );
  },
};
Enter fullscreen mode Exit fullscreen mode

组件(通用组件) -

# components/Loader/index.js

import React, { Component } from 'react';
import { View, ActivityIndicator } from 'react-native';
import Styles from './Styles';

function Loader(props)  {
    const { loading } = props;
    if (loading) {
        return (
            <View style={Styles.loaderWrapper}>
                <ActivityIndicator size="large" />
            </View>
        ) 
    } else {
        <View />
    }    
}

export default Loader;
Enter fullscreen mode Exit fullscreen mode

推介会 -

演示包含组件/容器。组件返回组件的设计,而容器包含组件的包装器,而 HOC Wrapper Of Connect(Redux)则使用 Redux Store | Props 将其连接到组件中。

让我们检查一下组件/容器的某些部分,它的作用和含义。

容器/组件 -

# component/ToDo/index.js

import React from 'react';
import { SafeAreaView } from 'react-native';
import TaskListContainer from '../../container/ToDo/TaskListContainer';
import Styles from './Styles';

function ToDoManagement() {
    return (
        <SafeAreaView style={Styles.container}>
            <TaskListContainer />
        </SafeAreaView>
    );
}

export default ToDoManagement;
Enter fullscreen mode Exit fullscreen mode
# container/ToDo/TaskListContainer.js

import { connect } from 'react-redux';
import TaskListComponent from '../../component/ToDo/TaskListComponent';

const mapStateToProps = ({ ToDo, loading }) => ({
    arrTasks: ToDo.arrTasks,
    loading: loading.effects.ToDo.fetchTasks,
  });

  const mapDispatchToProps = ({ 
      ToDo: { 
        fetchTasks,
        fetchTasksFromServer,
      } 
    }) => ({
        fetchTasks: () => fetchTasks(),
        fetchTasksFromServer: () => fetchTasksFromServer()
  });

  export default connect(mapStateToProps, mapDispatchToProps)(TaskListComponent);
Enter fullscreen mode Exit fullscreen mode
# component/ToDo/TaskListComponent.js

import React, { useEffect } from 'react';
import { SafeAreaView, FlatList } from 'react-native';
import TaskItemContainer from '../../container/ToDo/TaskItemContainer';

function TaskListComponent(props) {
    useEffect(() => {
        props.fetchTasks();
        props.fetchTasksFromServer();
    }, [])
    return (
        <FlatList
            data={props.arrTasks}
            renderItem={({ item, index }) =>
                <TaskItemContainer
                    {...item}
                />}
        />
    );
}

export default TaskListComponent;

Enter fullscreen mode Exit fullscreen mode

下载 React Clean Architecture 源代码!

感谢您阅读本文!

KPITENG | 数字化转型
www.kpiteng.com/blogs | hello@kpiteng.com

文章来源:https://dev.to/kpiteng/react-clean-architecture-114f
PREV
每个开发人员都应该使用的十大 React 技巧
NEXT
终极 React 阅读清单:2024 年必读的 15 篇文章