0

See GIF I'm building a simple search by tags in React. You have 10 posts on the page and each post has a tag. For example there are 2 tags "Cat" and "Cry" All tags are stored in local memory, no BD. If I input in my search a letter "C", then the page correctly renders posts with the "Cat" and "Cry" tags. But when I write "Ct" in the search bar, it renders again these 2 posts by the first letter but does not capture the subsequent letter "T". Please see GIF attached.

import React, { useEffect, useState } from "react";
import CardList from "../../features/CardList";
import SearchInput from "../../features/SearchInput";
import fetchFilms from "../../api/FetchAPI";
import { formatData } from "../../services/formatData";
import { useDispatch } from "react-redux";
import { filterTags, getFilmsList } from "../../store/actions";

function PageList() {
  const dispatch = useDispatch();
  const [request, setRequest] = useState("");

  async function getFilms() {
    const data = await fetchFilms();
    const dataFormat = formatData(data);
    dispatch(getFilmsList(dataFormat));
  }

  useEffect(() => {
    getFilms();
  }, []);

  function requestHandler(e) {
    console.log('request', request)
    setRequest(e.target.value);
    dispatch(filterTags(request));
  }

  return (
    <div>
      <SearchInput onChange={requestHandler} />
      <CardList />
    </div>
  );
}

export default PageList;

I expect that if I have tags Cat, Cry and I input Ct then no results show. I tried every solution offered on this forum with a similar title.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Implement the `dispatch` on a `useEffect` that has `request` as a dependency. State updates are only reflected on component's next render and that's why you are passing a stale state to `filterTags`. – ivanatias Nov 03 '22 at 00:24

1 Answers1

1

Instead of onChange, use onKeyPress event. Also, request state will not update right after you have set its value, because it is an asynchronous operation.

An alternative would be to dispatch your action directly with the input's value. Like so:

function requestHandler(e) {
    dispatch(filterTags(e.target.value));
  }
<SearchInput onKeyPress={requestHandler} />

onKeyPress docs

Caio Amorim
  • 165
  • 6
  • 2
    Changing from `onChange` to `onKeyPress` doesn't change how the React component lifecycle works. The `request` state still won't have updated in `requestHandler` when calling `dispatch(filterTags(request));`. – Drew Reese Nov 03 '22 at 00:18
  • That's true. What could work though is using the input's value to dispatch the action directly – Caio Amorim Nov 03 '22 at 00:22
  • Just edited my answer @DrewReese – Caio Amorim Nov 03 '22 at 00:28