Key is Matter in ReactJS
Adam C. |

React's key point is 'state', and the 'key' attribute is special and powerful. When a key changes, React will create a new component instance rather than update the current one, so the useSate will be called in the component.

Photo by Matt Botsford on Unsplash

First highly recommend reading this post from ReactJS Blog: https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html - it's old article and is not really related to the issue I have, but it explains what ‘key’ attribute is.

Here is a Child Component I have:

Rank.JS

export default function TimeTable({ swimmer }) {
  const {season, records} = swimmer;
  let defaultSeason = season;

  try {
    if (records && records.total > 0) {
      const mySeason = getSeason(records.data[0].date);
      defaultSeason = mySeason.season;
    }
  } catch (error) {}

  const ageGroup = getAgeGroup(rankingAge);
  const zone = getZone(lscCode);

  const [activeSeason, setActiveSeason] = useState(defaultSeason);
  ...
}

In the Parent Component I have:

Swimmer.js

import RANK from "./Rank.js";
const Swimmer = (props) => {
	....
	return(
		<Rank swimmer={props.swimmer} />
	)
}

So when calling “/swimmer/abc”, it renders <Swimmer> component, which renders <Rank> component,  where activeSeason is state via useState.  Note that activeSeason is calculated based on the current swimmer (abc.) After that, I call another swimmer “/swimmer/efg”, since it's under the same Router vis Next/Link, so the react only does update the existing Child (i.e., <Rank> component), and something probably very basic, although it still calculates the defaultSeason for the new swimmer ‘efg’, the state will not be set, because it only happens in a new component (i.e., the first component mount.) Therefore the activeSeason from the previous swimmer (abc) will be used regarding the new default value. 

To fix this, just need to add ‘key’.  Another solution could be adding useEffect with the swimmer as a dependency, so when the swimmer changes, set state by calling setActiveSeason. I certainly prefer to do this by adding a key:

import RANK from "./Rank.js";
const Swimmer = (props) => {
	....
	return(
		<Rank swimmer={props.swimmer} key={props.swimmer.id} />
	)
}