React: Trigger suspense from hooks

Created on 14 Feb 2019  ·  3Comments  ·  Source: facebook/react

Do you want to request a feature or report a bug?

Question. This may also be related to #14563.

How do we trigger suspense from a hook?

Why did the question come up?

This question came up during our usage of react-i18next. A recent update of react-i18next provided the useTranslation-hook which allows obtaining the current translations and will also trigger loading of not-yet-loaded translation namespaces (kinda like code splitting).

To handle the case where the translations aren't loaded yet, the useTranslation-hook throws a promise to trigger Suspense, which is actually really neat because it cleanly integrates with the existing react features!

However, if you are using more hooks after calling the useTranslation-hook, these other hooks won't be rendered if useTranslation throws the promise. Once the translations have loaded the hook won't throw anymore and react will award you with a big red warning that the amount of hooks has changed.

Example

const Component = () => {
  const [t] = useTranslation('translationnamespace');
  const [count, setCount] = useState(0);

  return (
    <div onClick={() => setCount(count + 1)}>
      {t('The count is:')} {count}
    </div>
  );
};

If translationnamespace isn't loaded yet, useTranslation will throw, causing useState to not be rendered. Once translationnamespace is loaded, useTranslation won't throw anymore, which causes useState to be rendered causing the warning.

The General Case

So this question doesn't apply to react-i18next only, but instead applies to all hooks that wish to trigger suspense. How would we go about doing this, and how would this integrate with the current "Rules of Hooks" that state that hooks mustn't be rendered conditionally?

Hooks Suspense Bug

Most helpful comment

I think we actually fixed this in 16.8.2. Please open a new one with a reproducing case if not.

All 3 comments

It seems like a mistake that the error fires in case of suspending. Afaik that was not intentional.

Alright, good to know!

Might also want to document that it is defined behavior to not render all hooks in case of suspension. But I presume this will be done once suspension is officially introduced as a data-fetching mechanism.

I think we actually fixed this in 16.8.2. Please open a new one with a reproducing case if not.

Was this page helpful?
0 / 5 - 0 ratings