0

I want to reload the App component when handleSearch() method updates the state of searchQuery using setSearchQuery(). but it does not re-render but after manually reloading it works. I am new to React so if it's a silly question, Please enlighten me. Thanks.

function App() {
  const [progress, setProgress] = useState(10);
  const API_KEY = process.env.REACT_APP_NEWS_APP_API;
  const [searchQuery, setSearchQuery] = useState("");
  useEffect(() => {
    console.log('Search Query Updated to : ', searchQuery); //It shwos the correct searchQuery.
  }, [searchQuery]);

  const handelSearch = (searchText) => {
    setSearchQuery(new String(searchText));
    console.log('Searching for : ', searchQuery);  //It remains empty
  }

  return (
    <div>
      <Router>
        <Header handelSearch={handelSearch} />
        <LoadingBar
          height={3}
          color='#f11946'
          progress={progress}
        />
        <Switch>
          <Route exact path="/">
            <News key="home" setProgress={setProgress} pageSize={15} country="in" apiKey={API_KEY} searchQuery={searchQuery} category="general" />
          </Route>
          <Route exact path="/general">
            <News key="general" setProgress={setProgress} pageSize={15} country="in" apiKey={API_KEY} searchQuery={searchQuery} category="general" />
          </Route>
          <Route exact path="/business">
            <News key="business" setProgress={setProgress} pageSize={15} country="in" apiKey={API_KEY} searchQuery={searchQuery} category="business" />
          </Route>
          <Route exact path="/science">
            <News key="science" setProgress={setProgress} pageSize={15} country="in" apiKey={API_KEY} searchQuery={searchQuery} category="science" />
          </Route>
          <Route exact path="/sports">
            <News key="sports" setProgress={setProgress} pageSize={15} country="in" apiKey={API_KEY} searchQuery={searchQuery} category="sports" />
          </Route>
          <Route exact path="/health">
            <News key="health" setProgress={setProgress} pageSize={15} country="in" apiKey={API_KEY} searchQuery={searchQuery} category="health" />
          </Route>
          <Route exact path="/technology">
            <News key="technology" setProgress={setProgress} pageSize={15} country="in" apiKey={API_KEY} searchQuery={searchQuery} category="technology" />
          </Route>
          <Route exact path="/entertainment">
            <News key="entertainment" setProgress={setProgress} pageSize={15} country="in" apiKey={API_KEY} searchQuery={searchQuery} category="entertainment" />
          </Route>
        </Switch>
      </Router>
    </div>
  );
}

export default App;

2 Answers2

0

Because state only has new value when component re render. So you should move console.log to outside handelSearch to check the new value when component re-render:

  const handelSearch = (searchText) => {
    setSearchQuery(new String(searchText));
  }

  console.log('Searching for : ', searchQuery);
Viet
  • 12,133
  • 2
  • 15
  • 21
  • This would be considered an unintentional side-effect if you are logging in the function body. Not necessarily adverse, but can sometimes lead to misleading logs. Best to stick to the console logging that's in the `useEffect` hook. – Drew Reese Sep 04 '21 at 05:20
0

In react, state updates happen asynchronously. Therefore, searchQuery state update won't be visible at the console.log you're putting in the following code-snippet.

  const handelSearch = (searchText) => {
    setSearchQuery(new String(searchText));
    console.log('Searching for : ', searchQuery);  // not visible due to async behaviour of setState function
  }
Kavindu Vindika
  • 2,449
  • 1
  • 13
  • 20