Categories
React Hooks

Top React Hooks — Form, Layout, and Async

Hooks contains our logic code in our React app.

We can create our own hooks and use hooks provided by other people.

In this article, we’ll look at some useful React hooks.

React Hook Form

React Hook Form is a useful form library to let us add forms to a React app easily.

To install it, we run:

npm install react-hook-form

Then we can use it by writing:

import React from "react";
import { useForm } from "react-hook-form";

export default function App() {
  const { register, handleSubmit, errors } = useForm();
  const onSubmit = data => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input name="firstname" ref={register} placeholder="first name" />
      <br />
      <input
        name="lastname"
        ref={register({ required: true })}
        placeholder="last name"
      />
      {errors.lastname && "last name is required."}
      <br />
      <input name="age" ref={register({ pattern: /d+/ })} placeholder="age" />
      {errors.age && "age must be a number"}
      <br />
      <input type="submit" />
    </form>
  );
}

We create our form with the inputs.

And we use the useForm hook to return some functions and objects we cause.

register lets us register our input so that we can use React Hook Form to do validation and handle input values.

errors has the errors for each field.

handleSubmit is a function that lets us handle submissions.

It takes a callback which we create to get the form data and do something with it.

The data parameter in onSubmit has the inputted data.

The register function takes an object with the pattern and required properties.

pattern has the validation pattern.

required indicates whether the field is required.

react-hook-layout

The react-hook-layout library lets us create layouts with a hook.

To install it, we can run:

npm install react-hook-layout

or:

yarn add react-hook-layout

Then we can use it by writing:

import React from "react";
import { defineSlots, useLayout } from "react-hook-layout";

export default function App() {
  const { Content, Footer, Header, SidebarLeft, SidebarRight } = defineSlots(
    "Content",
    "Footer",
    "Header",
    "SidebarLeft",
    "SidebarRight"
  );

  const Layout = useLayout();

  return (
    <Layout>
      <Content>content</Content>
      <Footer>footer</Footer>
      <Header>header</Header>
      <SidebarLeft>left</SidebarLeft>
      <SidebarRight>right</SidebarRight>
    </Layout>
  );
}

We use the defineSlots function to create our slots for the layout.

The arguments are the slot component names.

Then we can use the useLayout hook to create the Layout component to wrap around the slots.

react-hooks-async

The react-hooks-async library lets us make HTTP requests easily.

To install it, we run:

npm install react-hooks-async

Then we can use it by writing:

import React from "react";
import { useAsyncTask, useAsyncRun } from "react-hooks-async";

const fetchName = async ({ signal }, name) => {
  const response = await fetch(`https://api.agify.io/?name=${name}/`, {
    signal
  });
  const data = await response.json();
  return data;
};
export default function App() {
  const task = useAsyncTask(fetchName);
  useAsyncRun(task, "michael");
  const { pending, error, result, abort } = task;

  return (
    <>
      <p>{JSON.stringify(pending)}</p>
      <p>{JSON.stringify(error)}</p>
      <p>{JSON.stringify(abort)}</p>
      <p>{JSON.stringify(result)}</p>
    </>
  );
}

We created the fetchName function which takes an object with the signal property and parameters we pass in.

signal is the abort signal.

name is the parameter we want to pass in.

It returns a promise which resolves to the response data.

Then we can use the useAsyncTask hook with the fetchName function to return the task object.

We use this with the useAsyncRun hook with the argument we want to pass in.

Then task object has the pending , error , result , and abort properties.

pending indicates whether the result is pending.

error has any errors which come up.

result has the response body.

abort has the abort signal.

Conclusion

React Hook Form lets us create forms easily.

react-hook-layout lets us create layouts.

The react-hooks-async library lets us run async code with ease.

Categories
React Hooks

Top React Hooks — Fetch and State Helpers

Hooks contains our logic code in our React app.

We can create our own hooks and use hooks provided by other people.

In this article, we’ll look at some useful React hooks.

react-fetch-hook

The react-fetch-hook lets us fetch data from an API with a hook.

Its size is small and Flow and TypeScript types are included.

To install it, we can run:

yarn add react-fetch-hook

or:

npm i react-fetch-hook --save

Then we can use it by writing:

import React from "react";
import useFetch from "react-fetch-hook";

export default function App() {
  const { isLoading, data } = useFetch("https://api.agify.io/?name=michael");

  return isLoading ? <div>Loading...</div> : <>{JSON.stringify(data)}</>;
}

We use the useFetch hook with the URL of the API endpoint we want to get data from.

The isLoading has the loading state and data has the data.

It supports error handling and do multiple requests.

We can also format our data in a custom format.

react-hanger

The react-hanger library comes with various hooks we can use to do various things.

To install it, we run:

yarn add react-hanger

We can use the useInput hook to do automatic form value binding.

For instance, we can write:

import React from "react";
import { useInput } from "react-hanger";

export default function App() {
  const newTodo = useInput("");

  return (
    <>
      <input type="text" value={newTodo.value} onChange={newTodo.onChange} />
      <p>{newTodo.value}</p>
    </>
  );
}

The useInput hook returns an object which has the value and onChange properties that we can pass into the respective props.

The useBoolean lets us toggle the value of a boolean easily.

For instance, we can write:

import React from "react";
import { useBoolean } from "react-hanger";

export default function App() {
  const showCounter = useBoolean(true);

  return (
    <>
      <button onClick={showCounter.toggle}>toggle</button>
      <p>{showCounter.value.toString()}</p>
    </>
  );
}

The useNumber hook lets us set a number as long as it’s within a range.

For instance, we can write:

import React from "react";
import { useNumber } from "react-hanger";

export default function App() {
  const limitedNumber = useNumber(3, { lowerLimit: 0, upperLimit: 5 });

  return (
    <>
      <button onClick={() => limitedNumber.increase()}> increase </button>
      <button onClick={() => limitedNumber.decrease()}> decrease </button>
      <p>{limitedNumber.value}</p>
    </>
  );
}

We have the useNumber hook with an object with the lowerLimit and upperLimit properties.

Then we can use the increase and decrease methods to change the value property of limitedNumber .

We can’t set a number beyond the given range with it.

We can also add the loop option and set it to true so that the number will loop when it reaches the limits.

If we remove the object in the 2nd argument of the hook, then the number can be set to any value:

import React from "react";
import { useNumber } from "react-hanger";

export default function App() {
  const limitedNumber = useNumber(3);

  return (
    <>
      <button onClick={() => limitedNumber.increase()}> increase </button>
      <button onClick={() => limitedNumber.decrease()}> decrease </button>
      <p>{limitedNumber.value}</p>
    </>
  );
}

Conclusion

react-fetch-hook lets us fetch data from endpoints without hassle.

Also, we can use the react-hanger hook which various state helpers.

Categories
React Hooks

Top React Hooks — Cookies, Debounce, and Clipboard

Hooks contains our logic code in our React app.

We can create our own hooks and use hooks provided by other people.

In this article, we’ll look at some useful React hooks.

React Recipes

React Recipes comes with many hooks that we can use to do various things.

We can use the useCopyClipboard hook to let us copy any string to the clipboard.

For instance, we can write:

import React from "react";
import { useCopyClipboard } from "react-recipes";

export default function App() {
  const [isCopied, setIsCopied] = useCopyClipboard();

  const copy = () => {
    setIsCopied("copy string");
  };

  return (
    <button onClick={copy} type="button">
      {isCopied ? "Copied" : "Copy"}
    </button>
  );
}

to create a button to copy a string to the clipboard.

The useCopyClipboard hook returns an array with the isCopied and setIsCopied variables.

isCopied indicates that the string is copied to the clipboard if it’s true .

setIsCopied copies the string to the clipboard.

The useDarkMode hook lets us toggle on and off dark mode.

The setting will be saved in local storage.

For instance, we can write:

import React from "react";
import { useDarkMode } from "react-recipes";

export default function App() {
  const [darkMode, setDarkMode] = useDarkMode();

  return (
    <div>
      <button onClick={() => setDarkMode(!darkMode)}>toggle dark mode</button>
      <p>{darkMode.toString()}</p>
    </div>
  );
}

The setDarkMode function sets whether dark mode is on or not.

darkMode has the toggle state of dark mode.

The setting would be saved as an entry with the key dark-mode-enabled in local storage.

It doesn’t come with any styles, so we’ve to set the dark mode styles ourselves.

useDebounce is a hook that lets us denounce any fast-changing value.

For instance, we can use it by writing:

import React from "react";
import { useDebounce } from "react-recipes";

export default function App() {
  const [searchTerm, setSearchTerm] = React.useState("");
  const [result, setResult] = React.useState({});

  const debouncedSearchTerm = useDebounce(searchTerm, 500);

  const search = async () => {
    const res = await fetch(`https://api.agify.io/?name=${debouncedSearchTerm}`);
    const data = await res.json();
    setResult(data);
  };

  React.useEffect(() => {
    if (debouncedSearchTerm) {
      search();
    }
  }, [debouncedSearchTerm]);

  return (
    <div>
      <input value={searchTerm} onChange={e => setSearchTerm(e.target.value)} />
      <p>{JSON.stringify(result)}</p>
    </div>
  );
}

We use the useDebounce hook with the searchTerm state.

The 2nd argument is the delay to set the debouncedSearchTerm value in milliseconds.

Then we pass that into the array in the 2nd argument of useEffect to watch its value.

It’ll run the search function to get the data if debouncedSearchTerm is set.

The useDimensions hook let us get the dimension of any element.

To use it, we can write:

import React from "react";
import { useDimensions } from "react-recipes";

export default function App() {
  const [wrapperRef, dimensions] = useDimensions();

  return (
    <div ref={wrapperRef}>
      height: {dimensions.height}
      width: {dimensions.width}
    </div>
  );
}

The hook returns the wrapperRef that we pass as the value of the ref prop of the element that we want to watch the size of.

dimensions has the dimensions of the div that we passed the ref to.

Then as we change the size of the viewport, we’ll see the dimensions update.

Conclusion

React Recipes has hooks for rebounding, copying to clipboard, watching element sizes, and manipulating cookies.

Categories
React Hooks

Top React Hooks — Clipboard, APIs, and Forms

Hooks contains our logic code in our React app.

We can create our own hooks and use hooks provided by other people.

In this article, we’ll look at some useful React hooks.

react-use-clipboard

The react-use-clipboard library provides us with copy to clipboard functionality.

To install it, we run:

npm install react-use-clipboard --save-exact

or

yarn add react-use-clipboard --exact

Then we can use it by writing:

import React from "react";
import useClipboard from "react-use-clipboard";

export default function App() {
  const [isCopied, setCopied] = useClipboard("hello world");

  return (
    <button onClick={setCopied}>{isCopied ? "copied" : "not copied"}</button>
  );
}

We use the useClipboard hook with a string argument to let us copy it to the clipboard.

isCopied is a boolean to indicate whether it’s copied or not.

setCopied lets us copy the text to the clipboard.

We can reset the isCopied state after a period of time.

To do that, we can pass an object into the 2nd argument with the successDuration property:

import React from "react";
import useClipboard from "react-use-clipboard";

export default function App() {
  const [isCopied, setCopied] = useClipboard("hello world", {
    successDuration: 1000
  });

  return (
    <button onClick={setCopied}>{isCopied ? "copied" : "not copied"}</button>
  );
}

The number is in milliseconds.

react-use-data-loader

The react-use-data-loader library lets us load data with logic outside our component.

To install it, we run:

npm install --save react-use-data-loader

or:

yarn add react-use-data-loader

Then we can use it by writing;

import React from "react";
import { useDataLoader } from "react-use-data-loader";

async function getData(name) {
  const res = await fetch(`https://api.agify.io/?name=${name}`);
  const data = await res.json();
  return data;
}

export default function App() {
  const { data, error, loading, retry } = useDataLoader(getData, "michael");

  if (loading) {
    return <div>loading...</div>;
  }

  if (error) {
    return <div>Error</div>;
  }

  return (
    <>
      <div>{JSON.stringify(data)}</div>
    </>
  );
}

We have the getData function which returns a promise with the response body.

Then we can pass that into the useDataLoader hook so that we can get the data we want with it.

The 2nd argument of the hook is passed to the parameter of the getData function.

It returns the data , error , loading and retry properties.

data has the resolved data.

error has the errors object.

loading has the loading state.

react-use-form-state

The react-use-form-state library lets us create forms without hassle.

To install it, we run:

npm install --save react-use-form-state

Then we can use it by writing:

import React from "react";
import { useFormState } from "react-use-form-state";

export default function App() {
  const [formState, { text, email, password, radio }] = useFormState();

  function handleSubmit(e) {
    e.preventDefault();
    console.log(formState.values);
  }

  return (
    <form onSubmit={handleSubmit}>
      <input {...text("name")} placeholder="name" />
      <input {...email("email")} required placeholder="email" />
      <input
        {...password("password")}
        required
        minLength="8"
        placeholder="password"
      />
      <br />
      <input {...radio("plan", "free")} /> free
      <input {...radio("plan", "premium")} /> premium
      <br />
      <input type="submit" />
    </form>
  );
}

We use the useFormStare hook to create our form.

It returns an object with the formState with the form’s state, including the values, pristine, dirty, etc.

text , email , password , and radio are functions that we can call to add the type of input with the given name.

It returns an object with the value and form handler, which we can use in our input.

The first argument of these functions are the value of the name attribute.

The 2nd argument is the value of the value attribute.

Then we can get the form values with the formState.values .

Conclusion

react-use-clipboard lets us copy data to the clipboard.

react-use-data-loader lets us load data from APIs with ease.

react-use-form-state lets us create forms without the usual hard work.

Categories
React Hooks

Top React Hooks — Calendar, Form, and API

Hooks contains our logic code in our React app.

We can create our own hooks and use hooks provided by other people.

In this article, we’ll look at some useful React hooks.

react-uniformed

The react-uniformed package lets us create forms with ease.

To install it, we run:

npm install --save react-uniformed

or:

yarn add react-uniformed

to install it.

Then we can use it by writing:

import React from "react";
import { useForm, useSettersAsEventHandler } from "react-uniformed";

export default function App() {
  const { setValue, values, submit } = useForm({
    onSubmit: data => console.log(data)
  });

  const handleChange = useSettersAsEventHandler(setValue);

  return (
    <>
      <form onSubmit={submit}>
        <label>Name</label>
        <input name="name" value={values.name} onChange={handleChange} />

<button>Submit</button>
      </form>
    </>
  );
}

We created a basic form with the form element.

The useForm hook takes an object with the onSubmit method.

data has the data we submit.

The object it returns has the setValue , values , and submit properties.

setValue is used with the useSettersAsEventHandler hook to get the change handler function.

The submit function is passed into the submit prop.

React Use API

React Use API is another library that lets us make HTTP requests cleanly.

To use it, we run:

npm i react-use-api axios

or:

yarn add react-use-api axios

to install it.

Then we can use it by writing:

index.js

import React from "react";
import ReactDOM from "react-dom";
import { ApiProvider } from "react-use-api";

import App from "./App";

const rootElement = document.getElementById("root");
ReactDOM.render(
  <ApiProvider>
    <App />
  </ApiProvider>,
  rootElement
);

App.js

import React from "react";
import useApi from "react-use-api";

export default function App() {
  const [data, { loading, error }, request] = useApi({
    url: "https://api.agify.io?name=michael"
  });

  return (
    <>
      {loading && <div>Loading...</div>}
      {error && <div>{error.response.data.errMsg}</div>}
      {data && <>{JSON.stringify(data)}</>}
    </>
  );
}

We import the ApiProvider that wraps around the App component.

Then we can use the useApi hook by passing in an object with the url to the API.

That returns the data , loading , error and request objects.

data has the response body.

loading has the request loading state.

error has the error object.

request is a function that lets us make the request again.

react-use-calendar

The react-use-calendar library is a library that lets us add a calendar to our app.

To use it, we run:

npm install react-use-calendar --save

to install it.

Then we write:

import React from "react";
import useCalendar from "react-use-calendar";

export default function App() {
  const [state, actions] = useCalendar(null, {
    events: [
      {
        startDate: new Date(2020, 8, 27),
        endDate: new Date(2020, 8, 27),
        note: "meeting"
      },
      {
        startDate: new Date(2020, 8, 22),
        endDate: new Date(2020, 8, 25),
        note: "vacation"
      }
    ]
  });

  return (
    <table>
      <thead>
        <tr>
          <td colSpan={5} style={{ textAlign: "center" }}>
            <strong>
              {state.month} - {state.year}
            </strong>
          </td>
          <td colSpan={2} style={{ textAlign: "right" }}>
            <button onClick={() => actions.getPrevMonth()}>&lt;</button>
            <button onClick={() => actions.getNextMonth()}>&gt;</button>
          </td>
        </tr>
        <tr>
          {state.days.map(day => (
            <th key={day}>{day}</th>
          ))}
        </tr>
      </thead>
      <tbody>
        {state.weeks.map((week, index) => (
          <tr key={index}>
            {week.map(day => (
              <td
                key={day.dayOfMonth}
                style={{
                  textAlign: "center",
                  backgroundColor: day.isToday ? "orange" : "#fff"
                }}
              >
                {day.dayOfMonth}
              </td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  );
}

to use it.

We display the calendar with today’s date displayed in orange.

events is an array with calendar events.

We’ve to render the calendar and events ourselves with our own table.

Conclusion

react-uniformed lets us create a simple form.

React Use API lets us make API requests.

react-use-calendar is a hook that lets us create a calendar.