Home > Back-end >  React cannot get data from fetch api first time. I try my best but it didn't fetch data for the
React cannot get data from fetch api first time. I try my best but it didn't fetch data for the

Time:09-07

I didn't get data for the first time.

Here is my screen shot when I search for the first time it return undefined and when I search for second time it return proper data. enter image description here

How to I fix this problem. And please also explain what does it happens. I search this behavior from 2 days but I didn't find any solution even from stack overflow. Here is my code.

import logo from './logo.svg';
import './App.css';
import Navbar from './components/Navbar';
import { useEffect, useMemo, useState } from 'react'
function App() {
  const [searchWord, setSearchWord] = useState('');
  const [responseWord, setResponseWord] = useState();
  const [isLoad, setIsLoad] = useState(false)
  const [urlLink, setUrlLink] = useState('')
  async function fetchWord(word) {
    console.log(isLoad)
    const res = await fetch(`https://api.dictionaryapi.dev/api/v2/entries/en/${word}`);
    const data = await res.json();
    setIsLoad(true)
    setResponseWord(data)
    console.log(responseWord)
    console.log(isLoad)
  }

  return (
    <>
      <Navbar />
      <div className="container mt-4">
        <div className="row">
          <div className="column bg-success text-light text-center col-3" style={{ height: "100vh" }}>
            <h4> English Dictionary</h4>
          </div>
          <div className="column col-5 bg-light">
            {
              isLoad &&
              <>
                <h3 className='word'>{responseWord.word}</h3>
              </>
            }
          </div>
          <div className="row col-3" style={{ height: 50 }}>
            <form className="d-flex" role="search" onSubmit={(e) => e.preventDefault()}>
              <input className="form-control mr-sm-2" placeholder="Search"
                onChange={(e) => setSearchWord(e.target.value)}
                value={searchWord}
              />
              <button className="btn btn-outline-success my-2 my-sm-0" type="submit" onClick={() => fetchWord(searchWord)} >Search</button>
            </form>
          </div>

        </div>

      </div>
    </>
  );
}

export default App;

CodePudding user response:

When responseWord was printed the first time, responseWord's value was not updated to new value. Because setState operates asynchronously.

Use useEffect hook instead.

async function fetchWord(word) {
  console.log(isLoad)
  const res = await fetch(`https://api.dictionaryapi.dev/api/v2/entries/en/${word}`);
  const data = await res.json();
  setIsLoad(true)
  setResponseWord(data)
}

useEffect(() => {
  console.log(responseWord);
}, [responseWord]);

CodePudding user response:

can you try this one please i think will it help you out

    import React, { useEffect, useMemo, useState } from "react";
const App=()=> {
  const [searchWord, setSearchWord] = useState("");
  const [responseWord, setResponseWord] = useState([]);
  const [isLoad, setIsLoad] = useState(false);
  const [urlLink, setUrlLink] = useState("");
  const fetchWord = async (word) => {
    console.log(word);
    try {
      setIsLoad(false);
      const res = await fetch(
        `https://api.dictionaryapi.dev/api/v2/entries/en/${word}`
      );
      const data = await res.json();
      setIsLoad(true);
      setResponseWord(data);
    } catch (er) {
      setIsLoad(false);
    }
  };
  const HandleSubmit = (e) => {
    e.preventDefault();
    fetchWord(searchWord);
  };

  return (
    <>
       <Navbar /> 
      <div className="container mt-4">
        <div className="row">
          <div
            className="column bg-success text-light text-center col-3"
            style={{ height: "100vh" }}
          >
            <h4> English Dictionary</h4>
          </div>
          <div className="column col-5 bg-light">
            {isLoad && responseWord.length !== 0 && (
              <>
                {/* <h3 className="word">{responseWord.word}</h3> */}
                {responseWord.map((eg, i) => (
                  <h3 key={i || eg}>{eg.word}</h3>
                ))}
              </>
            )}
          </div>
          <div className="row col-3" style={{ height: 50 }}>
            <form className="d-flex" role="search" onSubmit={HandleSubmit}>
              <input
                className="form-control mr-sm-2"
                placeholder="Search"
                onChange={(e) => setSearchWord(e.target.value)}
                value={searchWord}
              />
              <button
                className="btn btn-outline-success my-2 my-sm-0"
                type="submit"
              >
                Search
              </button>
            </form>
          </div>
        </div>
      </div>
    </>
  );
}
export default App;

don't console inside the Asynce function cause async function will await until responce came so your results will be previous state and assign your useState intially with empty array that will work properly if in case empty data

  • Related