Home > Blockchain >  Fetch fires every second "onChange"
Fetch fires every second "onChange"

Time:05-16

Somehow my fetch only fires every second time, I select an item from list:

export default function App() {

...

  useEffect(() => {
    fetchBookData(books).then((payload) => setPayload(payload));
  }, [books]);

  
  const fetchBooksBySubject = () => {
      const options = {
        method: `GET`,
      };
      fetch(`${server}/books?subjects_like=${selectedValue}`, options)
      .then((response) => {
        if(response.ok){
          return response.json().then(setBookList)
        }
          throw new Error('Api is not available') 
        })
      .catch(error => {
        console.error('Error fetching data: ', error)
        setError(error)
      })
  }

  const handleChange = e => {
    setSelectedValue(e);
    fetchBooksBySubject();
  };

  if (!payload) {
    return <div>Please start the server</div>;
  }
  console.log(bookList)
  return (
    <div className="bg-blue-200">
      <div className="container mx-auto py-36 bg-blue-200">
        <div className="mt-12 px-96">
          <SubjectSelector 
            options={payload}
            selectedVal={selectedValue}
            handleChange={handleChange}/>
          <ShowcaseBooks selectedVal={selectedValue} />
          <ul>
            {bookList?.map((item) => {
              return(
                <li>{item.title}</li>
              )
            }
            )}
          </ul>
      </div>
    </div>
  </div>
  )
}

So fetchBooksBySubject delivers the bookList first as emty array, then logs correctly, howeverso I have to select two times, to see <li>{item.title}</li> updated. Why is this and how to fix it?

CodePudding user response:

Your selectedValue isn't really updated yet (it will happen only at the next rerender) at the point when you call fetchBooksBySubject. It happens because setSelectedValue doesn't update the associated value immediately.

As a result, fetch(`${server}/books?subjects_like=${selectedValue}`, options) gets an old value.

You could fix it with i.e. useEffect hook:

useEffect(() => {
  fetchBooksBySubject();
}, [selectedValue])

instead of calling fetchBooksBySubject immediately in the callback

  • Related