1

Hi I am getting data using axios in my App component and then showing it on the screen in my SearchResults component.

I currently make my get request (after the user has typed into an input field - in another component) and store all the data in my state searchResults using setSearchResults. Then I pass the data to my SearchResults component as a prop, and use & map through it, and based on some logic I display that correct data on the screen.

I want to know whether it would be more efficient to do my logic directly in my async func rather than in my function in SearchResults component.

I have attempted to do the logic in the async func (can be found below) but my results do not come out correctly. When a I type something in my inputfield, it retrieves data that is not relevant to what the user has typed. Would it be better to leave it as is? Is the reason it's not working because I'm setting my data from my get request incorrectly in my state hook? Any help is appreciated, thank you in advance!

function App() {
    const [keyword, setKeyword] = useState("")
    const [searchResults, setSearchResults] = useState([])

    const getAllData = async () => {
        return await getDataService(keyword)
            .then(({ data }) => {
                // currently I am just doing: 
                   setSearchResults(data.list)

                // my attempt below for doing the logic directly here 
                //instead of in showSearchResults() in my other component:
                return data.list.map((item) => {
                  if(item.searchterm.includes(keyword.toLowerCase())) {
                    setSearchResults([...searchResults, item])
                }
              })
            })
            .catch((err) => console.log(err))
    }

    return (
        <div className="App">
            <form className="container">
                <InputField keyword={keyword} setKeyword={setKeyword} getClothesData={getClothesData} />
                <SearchResults keyword={keyword} searchResults={searchResults} />
            </form>
        </div>
    );
}

const SearchResults = ({ keyword, searchResults }) => {
  const showSearchResults = () => {
    return searchResults.map((item, index) => {
      if (item.searchterm.includes(keyword.toLowerCase()) && keyword.length > 1) {
        return (
          <div className="text-bold" key={index}>
            <ul>
              <li className="input-fields search-results">
               {item.searchterm}
              </li>
            </ul>
          </div>
        );
      }
    });
  };
  return <div>{ keyword ? showSearchResults() : null }</div>;
}
critical_maas
  • 127
  • 1
  • 3
  • 9
  • firstly you should seperate fetch data and filter data sides. fetch data should be inside useEffect hooks. In addition, you can sperate to states for quick solution. – forever_software Jul 24 '20 at 10:51

2 Answers2

1

Make your server requests within useEffect hook: The template is like this:

const App = () => {
  const [state, setState] = useState([])
  
  useEffect(() => {
    axios(url).then(({ data }) => setState(data))
  }, []) // empty array here means that hooks works once

}
Tarukami
  • 1,160
  • 5
  • 8
0

Looks like the logic you're trying to apply is not correct.

return data.list.map((item) => {
  if(item.searchterm.includes(keyword.toLowerCase())) {
    setSearchResults([...searchResults, item])
}

Here, you're mapping over the items in list, and setting the searchResults state again and again. React will make it perhaps a batched update and will not always take the previous state value.

You can avoid that happening by providing functional update in setSearchResults

Take a look at Why React useState with functional update form is needed?

Dharman
  • 30,962
  • 25
  • 85
  • 135
brijesh-pant
  • 967
  • 1
  • 8
  • 16
  • So do you mean setting it up as: `setSearchResults(searchReslts => [...searchResults, item])` ? – critical_maas Jul 24 '20 at 11:17
  • @critical_maas Yup! Also, I'd like you to follow other answers shared here. For e.g the answer shared by Tarakumi – brijesh-pant Jul 24 '20 at 11:19
  • I followed his comment too! Thanks. I tried to do the suggestion with the functional update but I am still getting incorrect results. It displays all the items more than once, when I wanted the results that contain the keyword. – critical_maas Jul 24 '20 at 12:03