Logo
Logo

Blog

React Design Patterns

Stay informed on new product features, the latest in technology, solutions, and updates.

Sep 6, 2023

presentation

Design Patterns are the pre-built templates that help create websites and mobile applications efficiently. In simple terms, design patterns are the proven solutions to resolve common application problems and development challenges.

While the term "design patterns" might sound complex, it essentially refers to proven solutions to common coding challenges. Think of them as refined techniques discovered and refined by experienced developers. These patterns empower you to create React applications that are not only elegant but also exhibit qualities such as clarity, scalability, and resilience.

React Components design pattern

The higher-order component pattern

image

The Higher Order Component (HOC) pattern in React is a technique where a function takes a component and returns a new, enhanced component. This pattern allows for the reuse of logic across different components. Essentially, HOCs enable component composition by wrapping components with additional capabilities or modifying their behavior. It's a way to abstract and share common functionalities without directly altering the original components, helps in code modularity and reusability in React applications.

Here is an example of Higher order Component

import React, { Component } from 'react';

// Higher Order Component
const withUpperCase = WrappedComponent => {
return class extends Component {
render() {
// Enhance the original component by converting text to uppercase
const modifiedProps = {
...this.props,
text: this.props.text.toUpperCase()
};

// Render the enhanced component with modified props
return <WrappedComponent {...modifiedProps} />;
}
};
};

// Component
const Component = props => {
return <div>{props.text}</div>;
};

// Higher order component
const HOCComponent = withUpperCase(OriginalComponent);


const App = () => {
return (
<div>
<Component text="Hello, World!" />
<HOCComponent text="Hello, World!" />
</div>
);
};

The provider pattern

image

The Provider pattern in React involves using a provider component to share data or state across multiple components without having to pass it explicitly using props at each level of the component tree. It uses the Context API, enabling the creation of a central data store that components can access when needed. This helps us to maintain the states easily reducing the need for prop drilling and facilitates the management of global state within a React application.

Here is an example of Provider component

import { createContext } from 'react';

const ThemeContext = createContext();

export default ThemeContext;

// provider
import React, { useState } from 'react';
import ThemeContext from './ThemeContext';

const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light');

const toggleTheme = () => {
setTheme(prevTheme => (prevTheme === 'light' ? 'dark' : 'light'));
};

return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};

export default ThemeProvider;

// Component
import React, { useContext } from 'react';
import ThemeContext from './ThemeContext';

const ThemedComponent = () => {
const { theme, toggleTheme } = useContext(ThemeContext);

return (
<div style={{ background: theme === 'light' ? '#fff' : '#333', color: theme === 'light' ? '#333' : '#fff' }}>
<p>Current Theme: {theme}</p>
<button onClick={toggleTheme}>Toggle Theme</button>
</div>
);
};

export default ThemedComponent;

// App.js
import React from 'react';
import ThemeProvider from './ThemeProvider';
import ThemedComponent from './ThemedComponent';

const App = () => {
return (
<ThemeProvider>
<div>
<h1>Themed App</h1>
<ThemedComponent />
</div>
</ThemeProvider>
);
};

export default App;


The state reducer pattern

The Reducer pattern in React involves using the useReducer hook to manage state . It has a function called a "reducer" to handle state manipulation based on dispatched actions. This pattern is particularly useful for complex state logic. The reducer takes the current state and an action as inputs and returns the new state. using this pattern,we can achieve a more maintainable and scalable approach to state management within our applications.

Here is an example of useReducer hook

import React, { useReducer } from "react";

// reducer function
const themeReducer = (state, action) => {
switch (action.type) {
case "TOGGLE_THEME":
return { ...state, isDarkTheme: !state.isDarkTheme };
default:
return state;
}
};

// useReducer
const ThemedComponent = () => {
const [state, dispatch] = useReducer(themeReducer, { isDarkTheme: false });

return (
<div
style={{
background: state.isDarkTheme ? "#333" : "#fff",
color: state.isDarkTheme ? "#fff" : "#333",
}}
>
<p>Current Theme: {state.isDarkTheme ? "Dark" : "Light"}</p>
<button onClick={() => dispatch({ type: "TOGGLE_THEME" })}>
Toggle Theme
</button>
</div>
);
};

const App = () => {
return (
<div>
<h1>Themed App</h1>
<ThemedComponent />
</div>
);
};

export default App;

Controlled inputs

A controlled element in React is an input element whose value is controlled by the state of a React component. Instead of relying solely on the browser to manage the input's state, React components manage and update the input's value through state, allowing for more predictable and controlled behavior. This is achieved by setting the input value as a state variable and providing an onChange handler to update that state when the input changes. Controlled elements provide a centralized way to manage form data in React applications, enabling easy synchronization between the UI and component state.

Here is an example of controlled input

import React, { useState } from "react";

const ControlledInput = () => {
const [input, setInput] = useState("");

const inputChangeHandler = (e) => {
setInput(e.target.value);
};

return (
<div>
<input type="text" value={input} onChange={inputChangeHandler} />
</div>
);
};

export default ControlledInput;

The hook pattern

React Hooks, a feature introduced in React 16.8, have become intergral part in the evolution of React application development. These hooks, fundamental functions, serve as gateways for functional components to harness the power of state and lifecycle methods, previously exclusive to class components. What makes hooks particularly powerful is their adaptability – they can be tailored to meet specific component requirements, offering versatility beyond their primary use cases.

mostly used hooks are useState ,useEffect ,useRef etc.

Here is an example for custom hook for api request using axios

import { useEffect, useState } from "react";
import axios from "axios";

const useApiRequest = (url, options = {}) => {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(true);

useEffect(() => {
const fetchData = async () => {
try {
const response = await axios(url, options);
setData(response.data);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};

fetchData();
}, [url, options]);

return { data, error, loading };
};

export default useApiRequest;

Props Combination

Props combination is a pattern in React where related props are consolidated into a single object and passed as a unified prop to a component. This simplifies code, enhances readability, and is particularly useful when dealing with numerous related properties. By centralizing related props into a cohesive object, code becomes cleaner, more manageable, and helps reusability. It involves using object destructuring and the spread operator to efficiently handle and distribute props within components, making the codebase more organized and maintainable.

Here is an example of Props Combination

import React from 'react';


const Paragraph=({ color, size, children, ...rest }) =>{
return (
<p style={{ color, fontSize: size }} {...rest}>
{children}
</p>
);
}

// Parent Component
const App() =>{

const paragraphProps = {
color: "blue",
size: "16px",
fontWeight: "bold"
};

return <Paragraph {...paragraphProps}>This is a paragraph.</Paragraph>;
}

export default App;



Conclusion

In conclusion, React design patterns serve as invaluable guides for developers seeking to optimize their code. These patterns, akin to seasoned strategies, enhance the structure, scalability, and overall quality of React applications. As you embark on your coding endeavors, incorporating these patterns will undoubtedly empower you to create more efficient, maintainable, and robust solutions. Happy coding!

Logo

Crafting Quality Software in India, Shaping Global Excellence

Flag of India

Proudly building in India

A-401, Pramukh Anand Orbit Mall,
Kudasan, Gandhinagar, Gujarat 382421

© 2024 BigCircle. All rights reserved

This website uses cookies to ensure you get the best experience on our website. By continuing to use this site, you agree to our Cookie Policy