aralroca / next-translate

Next.js plugin + i18n API for Next.js 🌍 - Load page translations and use them in an easy way!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

t is unstable in appDir

jessemartin opened this issue · comments

What version of this package are you using?
2.6.2 (appDir)

What operating system, Node.js, and npm version?
N/A (present in all)

What happened?
The t function returned by the useTranslation hook is not stable.

Consider this problematic usage scenario, for example:

const { t } = useTranslation();

const [message, setMessage] = useState('');

const updateMessage = useCallback((evt) => { setMessage(evt.target.value); }, []);

const [triggerPostMessage, { isError: isPostMessageFailedError }] = usePostMessageMutation();

const postMessage = () => triggerPostMessage(message);

// This effect shows an error message if the post message request failed.
// `showToast` and `isPostMessageFailedError` are stable -- their references do not change when the component re-renders.
// However, `t` is unstable. So, every time this component re-renders (say, as `message` state is being updated by the user typing), this useEffect runs again, resulting in an additional toast being shown if in the error state.
// If `t` were instead stable, the effect would run only on `isPostMessageFailedError` transitions. And one toast would be shown when a transition into the error state occurs.
// There are many ways to work around this problem, but doing so should not be needed. `t` should be stable unless there is a good reason for it not to be.
useEffect(() => {
  if (isPostMessageFailedError) {
    showToast(t('post_message_failed_error_message'));
  }
}, [isPostMessageFailedError, showToast, t]);

return (
  <>
    <input onChange={updateMessage} value={message} />
    <button onClick={postMessage}>{t('post_message_button_text')}</button>
  </>
);

What did you expect to happen?
t should be a stable reference. This way, hooks that depend on it do not change on every render.

Are you willing to submit a pull request to fix this bug?
Yes, time allowing