Blog Details
Habibur Rahman
10 Oct 2024
3 min read
As React evolves, developers need to utilize advanced patterns to create efficient, maintainable applications. This guide explores key concepts including Higher-Order Components (HOCs), Render Props, the Context API, and performance optimization techniques.
A Higher-Order Component is a function that takes a component and returns a new component. It can provide additional props or features to the wrapped component.
const withExtraFunctionality = (WrappedComponent) => {
return (props) => {
// Logic to add extra functionality
return <WrappedComponent {...props} />;
};
};
Render Props is a technique for sharing code between components using a function that returns a React element.
Example:
Here’s a simple example using a toggle button.
import React, { useState } from 'react';
const Toggle = ({ render }) => {
const [isOn, setIsOn] = useState(false);
const toggle = () => {
setIsOn((prevState) => !prevState);
};
return render({ isOn, toggle });
};
export default Toggle;
The Context API is a way to share values (like state) between components without having to pass props manually at every level.
Example:
Let’s use context to provide user info globally.
// UserContext.js
import React, { createContext, useState } from 'react';
// Create the context
const UserContext = createContext();
// Create the provider component
export const UserProvider = ({ children }) => {
const [user, setUser] = useState({
username: 'JohnDoe',
email: 'johndoe@example.com',
});
const updateUser = (newUserData) => {
setUser((prevUser) => ({
...prevUser,
...newUserData,
}));
};
return (
<UserContext.Provider value={{ user, updateUser }}>
{children}
</UserContext.Provider>
);
};
export default UserContext;
// index.js or App.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { UserProvider } from './UserContext';
ReactDOM.render(
<UserProvider>
<App />
</UserProvider>,
document.getElementById('root')
);
// Profile.js
import React, { useContext, useState } from 'react';
import UserContext from './UserContext';
const Profile = () => {
const { user, updateUser } = useContext(UserContext);
const [newUsername, setNewUsername] = useState('');
const handleUpdate = () => {
updateUser({ username: newUsername });
setNewUsername(''); // Clear the input
};
return (
<div>
<h2>User Profile</h2>
<p>Username: {user.username}</p>
<p>Email: {user.email}</p>
<input
type="text"
value={newUsername}
onChange={(e) => setNewUsername(e.target.value)}
placeholder="New Username"
/>
<button onClick={handleUpdate}>Update Username</button>
</div>
);
};
export default Profile;
React.memo
is a way to optimize functional components by preventing them from re-rendering if their props haven’t changed.
Example:
Let’s create a simple component that only re-renders when the count
changes.
In this example, CounterDisplay
will only render when count
changes, improving performance by avoiding unnecessary renders.
import React, { useState } from 'react';
// CounterDisplay component wrapped with React.memo
const CounterDisplay = React.memo(({ count }) => {
console.log('CounterDisplay rendered');
return <h2>Count: {count}</h2>;
});
const App = () => {
const [count, setCount] = useState(0);
const [name, setName] = useState('');
const incrementCount = () => {
setCount(count + 1);
};
const handleNameChange = (e) => {
setName(e.target.value);
};
return (
<div>
<CounterDisplay count={count} />
<button onClick={incrementCount}>Increment Count</button>
<div>
<input
type="text"
value={name}
onChange={handleNameChange}
placeholder="Enter your name"
/>
<p>Your name is: {name}</p>
</div>
</div>
);
};
export default App;
These simplified examples show how to use Higher-Order Components, Render Props, the Context API, and React.memo
for optimization in React. By understanding and applying these concepts, you can build more efficient and maintainable React applications.
Don’t worry, we don’t spam!