An Interest In:
Web News this Week
- April 4, 2024
- April 3, 2024
- April 2, 2024
- April 1, 2024
- March 31, 2024
- March 30, 2024
- March 29, 2024
High reusability with high order components!
You have launched the best React application in the world, your users love it, but as the skilled software engineer that you are, you notice that you have created too many components that have similar functionality, resulting in a lot of duplicate code. It is now time to use one of the most powerful patterns in React, HOCs (high order components).
The purpose of a HOC is to enhance a given component with shared functionality and then returns a new component. This reusable HOC component is used to avoid creating too many similar components with that same enhanced functionality. It also improves the code of your application to become more extendable as you hire new engineers for your team to add new features for your users.
To help you identify opportunities to remove duplicate code in your application, we'll create an example HOC that will enhance its input components with a common shared functionality, toggling. The toggling functionality is useful in the following scenarios:
- Displaying/hiding a component
- Collapsing/expanding a list of components
In this post we will using the toggling functionality to:
- Toggle between a text and an input field. This will allow the user to toggle between editing and displaying a post title
- Toggle between collapsed/expanded list
Both of these cases need the same toggling functionality. We first implement the logic of toggling once when creating the HOC, and reuse this new HOC as many times as we want to create new components that will take advantage of using that same logic.
Lets start by creating the new HOC with the name withToggle
:
// withToggle.jsimport React, { useState } from "react";const withToggle = (Component) => ({ ...props }) => { const [toggleStatus, setToggleStatus] = useState(false); const toggle = () => { setToggleStatus((prevToggleStatus) => !prevToggleStatus); }; return <Component toggleStatus={toggleStatus} toggle={toggle} {...props} />;};export default withToggle;
What this HOC does is:
It accepts a Component as an input
It returns a component that has a toggleStatus state with an initial value of false, and toggle function that is used to update the toggleStatus state
It returns the given Component input with two additional props
- toggleStatus
- toggle
and a deconstructured props that enables us to pass any additional props from the user.
Overall this simple HOC returns the same component input but with two additional props, a boolean and a function to update that boolean.
Lets now use this HOC to implement our first use case:
// ViewEditToggle.jsimport React from "react";import withToggle from "./withToggle";const ViewEditToggle = ({ toggleStatus, toggle, title }) => ( <div> {toggleStatus ? <input type="text" value={title} /> : <p>{title}</p>} <button onClick={toggle}>{toggleStatus ? "Cancel" : "Edit"}</button> </div>);export default withToggle(ViewEditToggle);
When the toggleStatus state is updated to true, we display an input field and if false we display a
tag containing the title prop.
The toggle prop is passed in to the onClick handler of the button, which allows us to toggle the toggleStatus state when we click the button.
This example can be used to update the value of a post title. The user would click the toggle button and write a new value for the post title. The functionality to handle the change of the input and to submit a new value, can be achieved by creating an additional HOC.
Also, notice that we are exporting the withToggle
function with the ViewEditToggle
component as its input, and when we render ViewEditToggle
it will get its initial toggling props from the withToggle
HOC.
We can now use this component anywhere within our codebase with:
<ViewEditToggle title={"My first post"} />
Lets now use this HOC again to implement our second use case:
// CollapseExpand.jsimport React from "react";import withToggle from "./withToggle";const CollapseExpand = ({ toggleStatus, toggle, list }) => ( <div> <p>List of items</p> <button onClick={toggle}>{toggleStatus ? "Collapse" : "Expand"}</button> {toggleStatus && ( <div> {list.map((item) => ( <p key={item.id}>{item.name}</p> ))} </div> )} </div>);export default withToggle(CollapseExpand);
As with the first use case, the CollapseExpand component gets enhanced with the toggleStatus prop and the toggle function to achieve the toggling functionality.
We can now use this component anywhere within our codebase with:
const list = [ {id: 1, name: "Vue"}, {id: 2, name: "Angular"}, {id: 3, name: "React"}]<CollapseExpand list={list} />
Control props
Lets add a controller prop initialToggleStatus
to control the initialization of the toggleStatus state if a user needs to have the list initially expanded.
// withToggle.jsimport React, { useState } from "react";const withToggle = (Component) => ({ initialToggleStatus, ...props }) => { const [toggleStatus, setToggleStatus] = useState( initialToggleStatus || false ); const toggle = () => { setToggleStatus((prevToggleStatus) => !prevToggleStatus); }; return <Component toggleStatus={toggleStatus} toggle={toggle} {...props} />;};
If we pass the initialToggleStatus prop to the CollapseExpand component, we can now set the initial value of toggleStatus:
const list = [ {id: 1, name: "Vue"}, {id: 2, name: "Angular"}, {id: 3, name: "React"}]<CollapseExpand list={list} initialToggleStatus />
Original Link: https://dev.to/chrisipanaque/high-reusability-with-high-order-components-j0k
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To