0

I have a useEffect in my Routes in App.js

    <Switch>
      <Route exact path={['/en', '/fr']} component={HomePage} />
      <Route path={['/en/*', '/fr/*']}>
        <Route path="/:lang/*" component={DefaultLanguage} />

in the same file(App.js) we have the component like so (using react-localize-redux):

const DefaultLanguage = withLocalize(
  ({ activeLanguage, setActiveLanguage, ...props }) => {
    useEffect(() => {
      console.log('setting active language');
      setActiveLanguage(props.match.params.lang);
    }, []);
    return <></>;
  }
);

The problem is every link i click runs setActiveLanguage even though i put [] to make it only run on first render (because that's the only time I care about setting language from URL) I've had this issue in other parts of the app as well. From my understanding useEffect shouldn't run everytime the component is mounted unless its dependancies change, but it seems I'm missing a detail.

Avedis Kiyici
  • 67
  • 1
  • 7

1 Answers1

2

You are correct that passing an empty array to useEffect will stop it from running on subsequent renders, but that will not stop it from running if the component is unmounted and then mounted again.

My guess is that by clicking on your links you are actually un-mounting and then re-mounting your DefaultLanguage component.

You could test this by returning a cleanup function from your useEffect hook.

For example,

useEffect(() => {
      console.log('setting active language');
      setActiveLanguage(props.match.params.lang);

      return () => console.log('Unmounting');
    }, []);

If you are seeing that log, then you've found your problem.

A quick and dirty solution could be to check and see if the language has changed, and if so set it. That won't address the potentially unnecessary mount/unmount but will at least avoid setting the language again.

useEffect(() => {
      if (activeLanguage !== props.match.params.lang) {
        console.log('setting active language');
        setActiveLanguage(props.match.params.lang);
      }
    }, []);
RobertMcReed
  • 451
  • 2
  • 2
  • The detail I missed was the difference between render and mount. I didn't think a useEffect with `[]` would run again no matter what. This was very helpful. – Avedis Kiyici May 21 '19 at 15:22