React Hooks with Async-Await

vinodchauhan7

vinodchauhan7

Posted on September 23, 2019

React Hooks with Async-Await

Picture this, You have text box which can give list books from google store based on what you type on it. If no book available on that particular search query than show 'No Book Found'. By default, it will always show 'Search for Books'.

Scenario's :
1) No Search : 'Search for Books'.
2) No Result : 'No Book Found'.
3) Found Books : 'Show list of books'.

In above scenarios', we want our result to update after searching the topic on Google API's. This clearly shows that we need to use promises or 'Async-await' to achieve the results. But here we want to make our custom hook which search for books when we hit the search button and show the results.

Now the question is Why we want hooks in this case. Answer is very simple, because we want to make our code cleaner and single liner on final usage. It must be not redundant i.e DRY(Don't Repeat Yourself).



function App() {
  const [search, setSearch] = React.useState("");
  const [query, setQuery] = React.useState("");
  return (
    <div className="App">
      <h1>Search for Books on any Topic</h1>
      <form
        onSubmit={e => {
          e.preventDefault();
          setQuery(search);
        }}
      >
        <label>Search : </label>
        <input type="text" onChange={e => setSearch(e.target.value)} />
        <input type="submit" value="search" />
      </form>

      <h1>List Result on {query}</h1>
    </div>
  );


Enter fullscreen mode Exit fullscreen mode

Till now this is our simple code for getting the final search value in state 'query'. Now we make our custom Async hook to search on google Api's.



function useAsyncHook(searchBook) {
  const [result, setResult] = React.useState([]);
  const [loading, setLoading] = React.useState("false");

  React.useEffect(() => {
    async function fetchBookList() {
      try {
        setLoading("true");
        const response = await fetch(
          `https://www.googleapis.com/books/v1/volumes?q=${searchBook}`
        );

        const json = await response.json();
        // console.log(json);
        setResult(
          json.items.map(item => {
            console.log(item.volumeInfo.title);
            return item.volumeInfo.title;
          })
        );
      } catch (error) {
        setLoading("null");
      }
    }

    if (searchBook !== "") {
      fetchBookList();
    }
  }, [searchBook]);

  return [result, loading];
}



Enter fullscreen mode Exit fullscreen mode

We cannot use 'async' keyword with 'useEffect' callback method. It will result in race conditions.

We are fetching our books from google api and then updating our 'setResult' state with book title. React.useEffect method will only run when our 'searchBook' got change.



//Updated App Component
function App() {
  const [search, setSearch] = React.useState("");
  const [query, setQuery] = React.useState("");
  const [result, loading] = useAsyncHook(query);
  return (
    <div className="App">
      <h1>Search for Books on any Topic</h1>
      <form
        onSubmit={e => {
          e.preventDefault();
          setQuery(search);
        }}
      >
        <label>Search : </label>
        <input type="text" onChange={e => setSearch(e.target.value)} />
        <input type="submit" value="search" />
      </form>

      {loading === "false" ? (
        <h1>Search for Books</h1>
      ) : loading === "null" ? (
        <h1>No Book Found</h1>
      ) : (
        result.map(item => {
          return <p>Book Title : {item}</p>;
        })
      )}
    </div>
  );
}



Enter fullscreen mode Exit fullscreen mode

Alt Text

Src : Because Its One Life

💖 💪 🙅 🚩
vinodchauhan7
vinodchauhan7

Posted on September 23, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

React Hooks with Async-Await
react React Hooks with Async-Await

September 23, 2019