cdt
cdt

Reputation: 223

React: Fetch Data onSubmit, not on onChange

I got this code working pretty much how I want it. However, it's fetching & display data after each keystroke. I only want it to fetch once, when I hit submit.

Also, if there's anything i'm doing that's not "best practice" please let me know so I don't make silly mistakes in the future.

import React, { useEffect, useState } from "react";

export default function App() {
  const [data, setData] = useState(null);
  const [query, setQuery] = useState("");

  useEffect(() => {
    if (!query) return;

    async function fetchData() {
      const response = await fetch(
        `https://www.omdbapi.com/?apikey=2e8b5857&s=${query}`
      );
      const data = await response.json();
      const results = data.Search;
      setData(results);
    }

    fetchData();
  }, [query]);

  const handleSubmit = (e) => {
    e.preventDefault();
    setQuery(query);
  };

  return (
    <div
      style={{
        margin: 20,
      }}
    >
      <form onSubmit={handleSubmit}>
        <br />
        <label>
          Input Movie:{" "}
          <input
            type="text"
            placeholder="ex. Harry Potter"
            value={query}
            onChange={(e) => {
              setQuery(e.target.value);
            }}
          />
        </label>
        <input type="submit" value="Submit" onClick={() => setQuery} />
      </form>

      {data &&
        data.map((movie) => (
          <div key={movie.imdbID}>
            <h1>{movie.Title}</h1>

            <h4>
              {movie.Year} | {movie.imdbID}
            </h4>

            <img alt={movie.imdbID} src={`${movie.Poster}`} />
          </div>
        ))}
    </div>
  );
}

Upvotes: 1

Views: 3832

Answers (2)

Miguel Depiante
Miguel Depiante

Reputation: 34

Pass the code that is inside the useEffect, that is, the fetch function, inside the submit function. leaving useEffect unused

Upvotes: 0

Lakshya Thakur
Lakshya Thakur

Reputation: 8316

Since you only want it after submit, you can skip the useEffect with [query] and just copy the same logic inside your handleSubmit like so :-

import React, { useEffect, useState } from "react";

export default function App() {
  const [data, setData] = useState(null);
  const [query, setQuery] = useState("");


  const handleSubmit = (e) => {
    e.preventDefault();
    if (!query) return;

    async function fetchData() {
      const response = await fetch(
        `https://www.omdbapi.com/?apikey=2e8b5857&s=${query}`
      );
      const data = await response.json();
      const results = data.Search;
      setData(results);
    }
    fetchData();
  };

  return (
    <div
      style={{
        margin: 20,
      }}
    >
      <form onSubmit={handleSubmit}>
        <br />
        <label>
          Input Movie:{" "}
          <input
            type="text"
            placeholder="ex. Harry Potter"
            value={query}
            onChange={(e) => {
              setQuery(e.target.value);
            }}
          />
        </label>
        <input type="submit" value="Submit"/>
      </form>

      {data &&
        data.map((movie) => (
          <div key={movie.imdbID}>
            <h1>{movie.Title}</h1>

            <h4>
              {movie.Year} | {movie.imdbID}
            </h4>

            <img alt={movie.imdbID} src={`${movie.Poster}`} />
          </div>
        ))}
    </div>
  );
}

Here's the codesandbox :-

Edit Form submit API request

Upvotes: 2

Related Questions