Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
December 18, 2020 09:54 pm GMT

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).

what?

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.

yay!

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;
Enter fullscreen mode Exit fullscreen mode

What this HOC does is:

  1. It accepts a Component as an input

  2. 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

  3. 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);
Enter fullscreen mode Exit fullscreen mode

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"} />
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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} />
Enter fullscreen mode Exit fullscreen mode

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} />;};
Enter fullscreen mode Exit fullscreen mode

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 />
Enter fullscreen mode Exit fullscreen mode

done!


Original Link: https://dev.to/chrisipanaque/high-reusability-with-high-order-components-j0k

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