How can I create the custom hook in this code?

Question: You are given the "MyComponent " functional component. You need to extract the functionality of this component into a function namely "useUserCollection" that will return 4 thing:
{userCollection, loadUsers, filter, setFilter}
And call that function from the functional component. Also, make sure the custom function call will be made only when the filter variable changes.

App.js

import React from "react";

export default function App () {
  const [filter, setFilter] = React.useState("");
  const [userCollection, setUserCollection] = React.useState([]);

 //Load full list when the component gets mounted and filter gets updated
  React.useEffect(() => {
    fetch(`https://jsonplaceholder.typicode.com/users?name_like=${filter}`)
      .then(response => response.json())
      .then(json => setUserCollection(json));
  }, [filter]);

  return (
    <div>
      <input value={filter} onChange={e => setFilter(e.target.value)} />
      <ul>
        {userCollection.map((user, index) => (
          <li key={index}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
};

What I have done

import React from "react";

export const useUserCollection = () => {
    const [filter, setFilter] = React.useState("");
    const [userCollection, setUserCollection] = React.useState([]);

    function loadUsers () {
        fetch(`https://jsonplaceholder.typicode.com/users?name_like=${filter}`)
            .then(response => response.json())
            .then(json => setUserCollection(json));
    }

    //Load full list when the component gets mounted and filter gets updated
    React.useEffect(() => {
        loadUsers();
    }, [filter]);

    return({userCollection, loadUsers, filter, setFilter});
}

export default function App () {

    const {userCollection, loadUsers, filter, setFilter} = useUserCollection();

    return (
        <div>
            <input value={filter} onChange={e => setFilter(e.target.value)} />
            <ul>
                {userCollection.map((user, index) => (
                    <li key={index}>{user.name}</li>
                ))}
            </ul>
        </div>
    );
};

What warnings I am getting?

enter image description here

**How do I remove first warning? **

>Solution :

Firstly you need to include the loadUsers in the dependency array within useEffect:

React.useEffect(() => {
   loadUsers();
}, [loadUsers]);

Secondly, to avoid excessive re-renders (or even an endless loop), you will have to wrap the loadUsers with useCallback hook:

const loadUsers = useCallback(() => {
   fetch(...);
}, [filter]);

Leave a Reply