Telerik blogs

Let’s take a look at some useful premade React hooks other developers have shared.

React is a JavaScript library used for creating interactive web frontend applications. It is one of the most popular libraries because of its easy-to-use API.

React provides a few built-in hooks which we can use in components or use them to create our own hooks with self-contained reusable logic.

To make developing React apps easier, many developers have developed their own custom hooks and made them available for everyone to use. In this article, we will look at some useful premade React hooks.

React Query

React Query is a library that provides us with React hooks to make making HTTP requests easier from our React app. We can configure which HTTP client library to use to make the requests with React query.

To install the library, we run:

@tanstack/react-query

Then to use it, we write:

index.js

import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

import App from "./App";

const queryClient = new QueryClient();

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

root.render(
  <StrictMode>
    <QueryClientProvider client={queryClient}>
      <App />
    </QueryClientProvider>
  </StrictMode>
);

App.js

import { useQuery } from "@tanstack/react-query";

export default function App() {
  const { isLoading, error, data } = useQuery({
    queryKey: ["answer"],
    queryFn: async () => {
      const res = await fetch("https://yesno.wtf/api");
      return res.json();
    },
  });

  if (isLoading) return "Loading...";

  if (error) return "An error has occurred: " + error.message;

  return <div className="App">{data.answer}</div>;
}

We wrap the QueryClientProvider component around our React App entry point component so that we can use the useQuery hook in our app’s components.

In App, we call the useQuery hook with an object with the queryFn property that makes the request we want. We set it to a function that calls fetch to make a GET request to https://yesno.wtf/api and returns a promise with the response JSON object.

The useQuery hook returns an object with the data property containing the response data. The error property has the error response if there is any.

isLoading is a boolean flag that is true if the request is in progress.

The queryKey property is set to an array with the unique id for the request. We can put in anything that uniquely identifies the request in the array.

Redux

Redux is a popular library for managing global states in React apps. It can be used standalone or in React apps.

Redux is updated to include a hooks API which makes managing states easier by reducing the amount of boilerplate code needed.

To install it, we run:

@reduxjs/toolkit

Then we can use it by creating a store with some actions.

We can use the built-in hooks to dispatch the actions and get the states. To do this, we write:

import { createSlice } from "@reduxjs/toolkit";

export const counterSlice = createSlice({
  name: "counter",
  initialState: {
    value: 0,
  },
  reducers: {
    incrementByAmount: (state, action) => {
      state.value += action.payload;
    },
  },
});

export const { incrementByAmount } = counterSlice.actions;
export const selectCount = (state) => state.counter.value;
export default counterSlice.reducer;

to call the createSlice function with an object with the initialState property set to an object with the global states’ initial values.

Then we set the reducers property to an object with a method that is set to a function that takes the state global state object and the action which is an object of the action dispatched.

In the function, we add the payload value to the value state. We set the name property to 'counter' to name to store counter.

Next, we export the incrementByAmount action by accessing it from the counterSlice.actions property. Then we export the selectCount function which returns the counter store’s value state.

After that, we export the reducer property as the default export which has the reducer that we defined earlier to update the state.

Next in index.js, we write:

import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { Provider } from "react-redux";
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./counter";
import App from "./App";

const store = configureStore({
  reducer: {
    counter: counterReducer,
  },
});

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

root.render(
  <StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </StrictMode>
);

to call configureStore with an object that has the reducer property set to an object with the counter property set to counterReducer.

Then to make the Redux hooks available in our React app, we wrap the Provider component around our entry point App component.

We set the store to the store we created so we can access it in our app.

Finally, in App.js, we write:

import { useDispatch, useSelector } from "react-redux";
import { incrementByAmount } from "./counter";

export default function App() {
  const count = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();

  return (
    <div className="App">
      <button onClick={() => dispatch(incrementByAmount(2))}>increment</button>
      <p>{count}</p>
    </div>
  );
}

In it, we call the useSelector hook to return the value state’s value by calling it with a function to return the state’s value.

And then we call useDispatch to return the dispatch function we use to dispatch an action.

Next, we add a button which sets the onClick prop to a function that calls dispatch that calls the incrementByAmount action with 2 as the action.payload property value. As a result, the value state will be incremented by 2.

Then we display the latest value state amount by rendering the count.

useMedia

The useMedia hook lets us check the current screen size without writing our own code with plain JavaScript.

To install it, we run:

npm install --save use-media

Then to use it, we write:

import useMedia from "use-media";

export default function App() {
  const isWide = useMedia({ minWidth: "500px" });
  return (
    <div className="App">
      <p>{isWide.toString()}</p>
    </div>
  );
}

to call the useMedia hook with an object that checks if the minWidth of the screen is 500px. It then returns true if the condition in the object is matched and false otherwise.

React Hook Form

React doesn’t come with any way to validate forms. Therefore, many libraries are available to let us validate forms.

The React Hook Form library lets us add form validation forms in our React app.

To install it, we run:

npm install react-hook-form

Then we use it by writing:

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

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

  return (
    <div className="App">
      <form onSubmit={handleSubmit(onSubmit)}>
        <input defaultValue="name" {...register("name")} />
        <br />
        <input {...register("required", { required: true })} />
        <br />
        {errors.required && <span>This field is required</span>}
        <br />
        <input type="submit" />
      </form>
    </div>
  );
}

We call the useForm hook to return an object with various properties.

The register property is a function that we call to register the input with React Hook Form so it’s included with form validation.

We use the properties returned by register as prop values for the inputs we register. We call it with the name of the input. The errors property is an object with the form validation result with the name of the input as property names.

The onSubmit prop is set to the handleSubmit function called with our onSubmit function so that onSubmit is called only when all the fields are valid.

In onSubmit, we get the form values from the data parameter as an object. The watch function lets us watch form values that are inputted and returns the value.

React Hanger

The React Hanger library provides us with many React hooks we can use.

To install it, we run:

npm i react-hanger

Then we can use some of the hooks provided in our React app.

For instance, we use the useInput hook to let us bind our input to a state by writing:

App.js

import { useInput } from "react-hanger";

export default function App() {
  const name = useInput("");
  console.log(name.value);

  return (
    <div className="App">
      <input type="text" value={name.value} onChange={name.onChange} />
    </div>
  );
}

We call the useInput hook with the initial value of name.value. Then we set the value prop to name.value to show the input value. And we set the onChange prop to the name.onChange function to update the name.value value with the input value.

Another useful hook that React Hanger comes with is the useArray hook. We can call it to create an array state.

For instance, we write:

App.js

import { useArray } from "react-hanger";

export default function App() {
  const { value, push, pop } = useArray([]);

  return (
    <div className="App">
      <button onClick={() => push(Math.random())}>push</button>
      <button onClick={() => pop()}>pop</button>
      <p>{JSON.stringify(value)}</p>
    </div>
  );
}

to call the useArray hook and set the value property’s initial value to an empty array.

Then we call push in the first onClick handler to append a random number to the value array. And we call pop in the second onClick handler to remove the last item from the value array.

Conclusion

To make developing React apps easier, many developers have developed their own custom hooks and made them available for everyone to use.

There are premade hooks to let us do many things, including making HTTP requests, adding form validation, storing local and global states and more.


About the Author

John Au-Yeung

John Au-Yeung is a frontend developer with 6+ years of experience. He is an avid blogger (visit his site at https://thewebdev.info/) and the author of Vue.js 3 By Example.

Related Posts

Comments

Comments are disabled in preview mode.