Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 23, 2021 01:34 pm GMT

React Clean Architecture

Hello Developers! Many of us use various design patterns with React Development to make React Apps more clean, clearly understandable, and more structured. But still we are facing issues with coding standards, we changed at one place and it breaks at another place. Is there any resolution for this? Yes, Try React Clean Architecture!

Quick Highlights - React Clean Architecture - which makes your code more structured, clean and anyone can easily take over your code and start working with you. So Lets continue next. Which include everything API, State Management (Redux, Redux Saga), Storybook, Utilities, Component/Container and you can add more relevant features in defined structure hierarchy.

React Clean Architecture Covered -

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

Application -

Application directory contains the State Management and Common utilities functions and constants. For State Management - I have used Redux Rematch, you can use Redux, Redux Saga, MobX State Management. For Common - I have used Fonts, Colours, Global Constants and Common Functions.

Lets check some parts of Rematch and Understand what it does and what it means.

Store -

# 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],  },});

Here, I am initialize Redux Store, to initialize Redux Store we require models, plugins, middleware (optional).

PlugIns -

PlugIns itself means to add some value to Redux Store.Here, we are using Loading PlugIns means it will show loading indicator while API is fetching data. So we can show Loader to user, once data is fetched Loading plugin update loading State and based on that we can hide loaders in components.

import createLoadingPlugin from '@rematch/loading';export const loadingPlugin = createLoadingPlugin({  whitelist: ['ToDo/fetchTasks'],});

Persists -

Persist itself means to Persist something, Here, it will persist Rematch Store. To create persist store it will take few argument, key, whitelist (model - save in persist store), blacklist (model - not saved in persist store), version - help while upgrading application, storage - AsyncStorage (store persist store in AsyncStorage), transform - contains - filters which applied while persist store.

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,});

Models -

Models will contain State, Reducer, Effect (Actions).

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) {      }    },  }),};

Filters -

import { createBlacklistFilter } from 'redux-persist-transform-filter';const toDoFilter = createBlacklistFilter('ToDo', ['totalTasks']);export const AllFilters = [toDoFilter];

Common -

Here, You can define your Global Constant, Common Files - Fonts, FontSize, Device Specification, Colors many more as per custom solution.

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 Messagesexport 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.";

Read Best JavaScript Coding Practices

Infrastructure -

Infrastructure contains API (Services) Files, API Handlers, Common Components like Loader, Common TextField, Buttons, etc. Here, I have used AXIOS, you can use JavaScript Fetch and create your API Wrapper class here.

Lets check some parts of Insfrastructure and Understand what it does and what it means.

Read More About - Zero Bundle Size - React Server Components

API (Services) -

# api/api/List.jsimport APIHandler from '../APIHandler';import * as Globals from '../../../application/common/Globals';export default {  getListData: () => APIHandler.get(Globals.TaskList),};
# api/APIHandler.jsimport { 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),    );  },};

Components (Common Components) -

# components/Loader/index.jsimport 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;

Presentation -

Presentation contains Component/Container. Component return design of your component, While Container contain wrapper of Component, HOC Wrapper Of Connect (Redux) to use Redux Store | Props into Components.

Lets check some parts of Component/Container, what it does and what it means.

Container/Components -

# component/ToDo/index.jsimport 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;
# container/ToDo/TaskListContainer.jsimport { 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);
# component/ToDo/TaskListComponent.jsimport 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;

Download React Clean Architecture Source Code!

Thanks for reading Article!

KPITENG | DIGITAL TRANSFORMATION
www.kpiteng.com/blogs | [email protected]


Original Link: https://dev.to/kpiteng/react-clean-architecture-114f

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To