For enquiries call:
+1-469-442-0620
HomeBlogWeb DevelopmentReact Architecture Pattern: Implementation + Best Practices
React comes with so many features that help you develop fantastic User Interfaces. One cool thing with React is that it doesn't force you to use a predefined architectural pattern like other JavaScript frameworks do. That is to say, React allows you to determine the structure of your application by yourself. An architectural pattern in front-end development is the blueprint of the User Interface. Becoming an in-demand frontend developer is now easier, check out our online Web Development Certificate courses. You can go through this article to get better clarity on React Architecture's best practices.
React architecture is a collection of components responsible for building a software’s User Interface (UI). You can also see it as an organization of your codebase that helps you build your unique project.
For example, a React architecture will include several UI components such as buttons, forms, API services, Central State Management services, etc.
Because of this ReactJs architectural freedom, it is the most preferred JavaScript library (framework) for building front-end applications. Get to know more about React.js features.
The following are some of the ways React architecture helps in web development:
1. React assists you in developing a component-based software architecture that simplifies maintenance and code reuse.
2. It enables you to maintain a global state variable by utilizing state management libraries such as Redux.
3. Because React architecture allows you to build out components, code expansion becomes much easier as your project grows.
4. Since it is component-based, the React architecture makes unit testing much easier.
Know more about React.js state.
Every React project has an architectural representation that is tailored to the project's purpose and dependencies. A React Web3 project, for example, will not have the same architecture as a React PWA project. However, when getting started with React, we recommend following the structure below which includes:
Using the example below, a React project has a source (src) folder where all the essential files and folders are listed:
└── /src
├── /assets
├── /components
├── /views
├── /services
├── /utils
├── /hooks
├── /store
└── App.js
├── index.js
├── index.css
Because React is a non-opinionated framework, it doesn't care how you divide your modules when building your application. But what exactly are modules? They are bundled reusable sets of functions, classes, and components that aid in the software development process.
React assists you in reducing complexity and creating open, reusable, and shared structures across your application. Common modules include reusable custom components, custom hooks, business logic, constants, and utility functions.
These modules, which are shared throughout your software, can be used in a variety of components, views, and even projects.
Below is an example of a React custom input component. In your components directory, create a new folder called Input. Now, within this input folder create the files represented below:
└── /src
├── /components
| ├── /Input
| | ├── Input.js
| | ├── Input.css
| | ├── Input.test.js
Next, you will then have to create an index.js file in the components directory to bundle up the components. See the code below for example:
// /src/components/index.js import { Button } from './Button/Button'; import { Input } from './Input/Input'; import { Card } from './Card/Card'; export { Button, Card, Input };
With this file set up, you can then use it on any view or pages in your project.
A custom Hook is a function that begins with "use" and may invoke other Hooks. Understanding this definition will help you use custom hooks effectively. Creating a custom hook is essential for reducing code complexity.
For example, let’s say that you have two distinct pages in your React app called a Login and Registration page. Each of these pages has input fields where visitors may enter their information and submit at the click of a button. If you want a password visibility toggling feature as part of the password field in both the pages, you may have to duplicate your code.
To reduce duplications and complexities from your codebase, writing a custom hook that toggles the password's visibility is the right approach. Here's an example of a custom hook:
Create a hook as described in the code snippet below:
└── /src ├── /hooks ├──usePasswordToggler.js
Paste the codes below into the usePasswordToggler file and save.
// ./src/hooks/usePasswordToggler.js import {useState} from 'react'; export const usePasswordToggler = () => { const [passwordVisibility, setPasswordVisibility] = useState(true); const [type, setType] = useState('password'); const handlePasswordVisibility = () => { if (type === 'password') { setType('text'); setPasswordVisibility(!passwordVisibility); } else if (type === 'text') { setType('password'); setPasswordVisibility(!passwordVisibility); } }; return { type, passwordVisibility, handlePasswordVisibility }; };
The above custom hooks are used to create a state of a hook with three objects it returns:
Next, you can use this hook in your regular React component, see the example below:
import React from 'react'; import { usePasswordToggler } from './hooks/usePasswordToggler'; import './App.css'; function App() { const { type, passwordVisibility, handlePasswordVisibility } = usePasswordToggler() return ( <main> <div> <input type={type} placeholder='Enter password...' /> <button onClick={handlePasswordVisibility}>{passwordVisibility ? 'Show' : 'Hide'} Password</button> </div> </main> ); }
export default App;
The above codes will produce the following outputs:
And that is how to create and utilize a React custom hook.
By default, React apps with nested directory structures might lead to confusion on the import path such as the example below:
// some file import { Button } from '../../components';
You can resolve a potential confusion on the directory paths by adding support for importing modules using absolute paths to your React application.
A rule can be added to the jsconfig.json file at the root of your project to resolve confusions with your folder paths. But what is jsconfig.json file? It's a configuration file that helps your editor's Language Server Protocol understand the JavaScript in your project folder.
Here is an example within the jsconfig.json file which can improve your directory path:
{ "compilerOptions": { "baseUrl": "src" }, "include": ["src"] }
Now, with this modification, you can import components located at /src/components this way:
import { Button } from 'components';
If your project includes webpack.config.js at the root, you may further personalize it by using a prefix such
as @components or ~components. See the configuration below:
module.exports = { resolve: { extensions: ['js'], alias: { '@': path.resolve(__dirname, 'src'), '@components': path.resolve(__dirname, 'src/components') '@hooks': path.resolve(__dirname, 'src/hooks'), } } };
With the above configurations, still using the previous example, you can now set absolute path for your component as follows:
import { Button } from '@components';
Isn’t that a lot cleaner?
The ability to review exactly what happens in someone else's browser but at a later time is referred to as session replay. It's not a recorded screen capture because that wouldn't allow you to play with the details, inspect the dev tools, or see what JavaScript errors appeared that were invisible to the user. I'm referring to a direct replay of the real DOM changing second by second.
There are various session replay tools available, but the one we'll be discussing today is OpenReplay. Why OpenReplay specifically? Because it provides a fully functional open-source version that you can download and install.
Another reason why OpenReplay is highly recommended is because of its ease of use. For example, by signing up, you'll be given a JavaScript snippet to include in your code. It works similarly to Google Analytic's snippet in that you copy and paste it there and it just works.
The image below shows a session replay recording being reproduced from an application user interface.
To improve the quality of your codes and make maintenance a lot easier, it is highly recommended that you separate logic from the UI components. The user interface structure of each page should be stored in the /pages or /views directory as React components.
As previously discussed, one of the patterns to distinguish the UI structure from the business logic is to build a custom hook. Here is an example of an app that retrieves users from an endpoint, to separate the logic from the UI, we created a file in the services folder >> api.js and pasted the codes below:
import axios from 'axios'; const api = { fetchUsers: async () => { const URL = 'https://jsonplaceholder.typicode.com/users'; return await axios.get(URL) .then((res) => res) .catch((err) => err) } } export default api;
The above code takes care of the business logic, now let’s hook up the user interface with the code below:
import './App.css' import api from './services/api' import { useState } from 'react' function App() { const [users, setUsers] = useState([]) const getUsers = () => { api .fetchUsers() .then((res) => setUsers(res.data)) } return ( <main> <div> <pre className="api__result">{ JSON.stringify(users, null, 2) }</pre> <button onClick={getUsers}>Get Users</button> <button onClick={() => setUsers([])}>Clear</button> </div> </main> ); } export default App;
And this is how the output looks like:
And that is how you simply separate business logic from the view (UI).
Utils folder as previously explained contains some helper functions to be used across your application. It is not required though, but for maintaining the rules of clean coding, it is recommended that you include it in your application. For example, here is how you would package a utility function.
Let’s create a file utils >> helper.js and paste the codes below inside of it:
const fileName = 'Helper' const truncate = (str, num) => { if (str.length > num) { return str.slice(0, num) + "..."; } else { return str; } } const navigateTo = (route) => { window.location.href = route; } const genStr = () => { return (Math.random() + 1).toString(36).substring(2); } export { fileName, truncate, navigateTo, genStr }
With the above codes, you can then import and use them in your respective projects:
One of the most common problems in a React app is figuring out how to share state across multiple components.
The complexity emerges when there are several components in between the parent and a child component. This results in an awkward situation called passing props.
React Context allows you to transmit data via the component tree without prop drilling, which is actually a method that allows a parent component to offer props to the whole tree of children underneath it. Sharing data becomes easier using this method eliminating the need to pass props.
Your React project should have various Contexts for accomplishing different tasks. You are not required to disclose data if a component of the application doesn’t require it. For example, your theme context should not contain codes for your API context and should only wrap the child components that will have a need for Theme state. See the example below:
const App = () => { return ( <ThemeProvider> <QueryClientProvider> <Routes /> </QueryClientProvider> </ThemeProvider> ) }
The above image describes a React architecture for building a large web application. This architecture uses React libraries such as Redux Saga which is a middleware that allows your store to interact asynchronously with resources outside of itself. It also uses Axios for accessing API resources on external servers such as on AWS (amazon web services).
Here are some of the reasons why the architecture is suited for creating large React apps:
The following are some general guidelines for creating a scalable and optimized React application:
1. Avoid using an excessive number of nested files and directories, and don't overthink on the application structure.
2. Don't move files around; you can't afford to change file locations when a team of developers is working on the same project.
3. As the number of components in your React project grows, be intentional about your naming conventions. Facebook's codebase contains over 30,000 React components, which they keep up-to-date by following well-defined component naming standards.
4. Separate your features into separate reducers, with each one exporting its action creators and selectors, so that teams can work on them more effectively.
5. Use Redux-saga in your project to manage a large amount of asynchronous code and side effects.
And there you have it for the best practices for ReactJs architecture patterns.
Looking for a Python course? Look no further! Discover the power of Python and unlock endless career opportunities. Join our unique program today!
As always, it has been fun dishing out this much information to you, hope you got a ton of value from this tutorial.
If you want to speed up your software development career, kindly check out React.js syllabus KnowledgeHut.
React architecture is a collection of components and software modules that helps you as a developer build an application’s user interface (UI).
The best architecture for ReactJs is dependent on the purpose and size of the application. However, it is recommended that your React architecture has components, views, hooks, utils, and store folders.
Yes, it is, a React application can be segmented into components and later combined to form the overall interface of your app.
ReactJS uses HOC pattern, which stands for higher-order-component. It is an advanced design that allows us to reuse component codes across an application. HOC pattern is perfect for features that require component logic to be shared across our application.
Name | Date | Fee | Know more |
---|