1

I am using React 17.0.2 with react-router-dom 5.2.0 and react-transition-group 4.4.2.

I have a header component with a search bar. The concerned code is as follows

const history = useHistory(); 
const [searchBarText, setsearchBarText] = useState(""); 

return(
<NavItem>
  <div>
    <input type="text" name="search" value={searchBarText} onChange={(e)=> setsearchBarText(e.target.value)} onKeyPress={(e) => { if (e.key === "Enter") { history.push("/search?q=" + searchBarText); console.log( "...pushed to history: ", searchBarText,
    " history is : ", history ); setsearchBarText(""); } }} />
    <NavLink to={ "/search?q=" + searchBarText} onClick={()=> setsearchBarText("")} >
      <i className="fas fa-search"></i>
    </NavLink>
  </div>
</NavItem>
);

The simplified routing is as follows:

const location = useLocation(); const SearchWithQuery = ({ location }) => (
<Search queries={getQueryObjects(location.search)} /> ); return (
<Header />
<TransitionGroup>
  <CSSTransition key={location.key} classNames="slide" timeout={2000}>
    <Switch location={location}>
      //all routes
      <Route path="/search" component={ SearchWithQuery} />
    </Switch>
  </CSSTransition>
</TransitionGroup>
);

The simplified index.js is wrapped inside router as follows

import { BrowserRouter} from "react-router-dom";
<BrowserRouter>
  <App />
</BrowserRouter>

The simplified search component is as follows:

const Search = ({ queries }) => {
  console.log("...from search component: queries: ", queries);
  return <></>;
};

export default Search;

The normal behavior should be as:-

  • Clicking on search icon or pressing enter after typing some text calls history.push() with provided url and query and the specific component should be rendered as per the given url.
  • On rendering, console.log displays the props which has location, history and match. the location key has search key to get query. This query is logged to console.

The actual behaviour is as:

  • On pressing search or entering enter, console shows props with typed query (as expected) and follows further routines and checks
  • After certain time (almost 0 seconds) component is re-rendered again, but this time with old props (i.e. the query string I typed earlier than this string). This thing causes additional data to be loaded and shown to user (current query already loaded and old query response gets loaded also).

The console response is shown below. first I searched "old" and then "new" in search box

Console Response

My question is Why is my search component being re-rendered with "old" query after being rendered with "new" query?

This is to be noted that, when I reload the page using chrome reload button or when I am on tab other than search, then only "new" query response is shown. The above error occurs only when I am already on search tab with some "old" query result shown and want to search for something else ("new" query).

Update 1:

I have found out that problem occurs when I encapsulate my routing inside TransitionGroup and CSSTransition component. Without that, output is as expected. But still I am not able to solve the issue though. I have created a sandbox with minimal setup which replicates the issue.

MSM
  • 410
  • 6
  • 16

0 Answers0