Nextjs 9 вызывает getInitialProps на стороне клиента - PullRequest
0 голосов
/ 02 ноября 2019

У меня была базовая страница, которую я использовал в качестве начальной загрузки для NextJS с TypeScript, React, Redux и другими вещами, такими как i18n, jest и т. Д., Которая отлично работала в Nextjs 8, но когда я обновил ее до последней версии(9) перестал работать.

Перестал работать в том смысле, что страница продолжает «перезагружаться» или «перерисовываться» при изменении состояния. И я имею в виду, метод getInitialProps вызывается на стороне клиента (без участия Link)

У меня есть пользовательский файл _app.tsx с этим методом визуализации:

public render() {
  const { Component, pageProps } = this.props;
  const state = getOrCreateState();

  if (!IS_SERVER) {
    initLogger(state.settings.log);
    Component.logger = getLogger(Component.name);
  }

  const store = createStore(state, mainReducer);
  // tslint:disable-next-line: no-console
  console.log(`Rendering ${Component.name}`, store.getState());

  return (
    <>
      <Provider store={store}>
        <Component {...pageProps} />
      </Provider>
      <div
        dangerouslySetInnerHTML={{ __html: Main.getStoreScriptHtml(state) }}
      />
    </>
  );
}

(без остального, потому что он работал на v8, это правильный код, но с render вы можете увидеть организацию)

Единственное, Component в этом случае (страница)вот так:

const IndexPage: PageComponent = function IndexPage() {
  const glitch = useSelector((state: State) => state.template.glitch);
  const dispatch = useDispatch();

  React.useEffect(initPage(glitch, dispatch), []);

  const DynamicTemplate = dynamic(
    () => import('../components/_template' as string).then(mod => mod.Template),
    { loading: () => <p>Loading...</p> }
  ) as React.ComponentType<Pick<TemplateProps, 'glitch'>>;

  return <DynamicTemplate glitch={glitch} />;
};

IndexPage.getInitialProps = async () => {
  /*
   * Example of Logger usage inside a component.
   * This mainly will be triggered in server side (unless navigating through <Link>)
   */
  IndexPage.logger.error('getInitialProps: error msg');
  IndexPage.logger.warn('getInitialProps: warn msg');
  IndexPage.logger.info('getInitialProps: info msg');
  IndexPage.logger.verbose('getInitialProps: verbose msg');
  IndexPage.logger.debug('getInitialProps: debug msg');
};

/**
 * Initialize the page when it's mounted, triggering a dispatch to change the state of the
 * glitch every few milliseconds, generating the "hacky" effect
 */
function initPage(initialGlitch: boolean, dispatch: ThunkDispatch) {
  return () => {
    const GLITCH_TIME = 200;
    const NORMAL_TIME = 1500;
    let glitch = initialGlitch;
    let timeoutHandler: number;

    function changeGlitch() {
      glitch = !glitch;
      dispatch(I18nSetLang(glitch ? 'es' : 'en'));
      dispatch(TemplateSetGlitchAction());
      timeoutHandler = setTimeout(
        changeGlitch,
        glitch ? GLITCH_TIME : NORMAL_TIME
      );
    }

    changeGlitch();

    /*
     * Example of Logger usage.
     * This mainly will be triggered in client side
     */
    IndexPage.logger.error('initPage: error msg');
    IndexPage.logger.warn('initPage: warn msg');
    IndexPage.logger.info('initPage: info msg');
    IndexPage.logger.verbose('initPage: verbose msg');
    IndexPage.logger.debug('initPage: debug msg');

    return () => clearTimeout(timeoutHandler);
  };
}

export default IndexPage;

Итак, главное, чтобы протестировать React / Redux, это просто страница, которая переключается между true / false свойством glitch для перерисовки Templateкомпонент (который также выполняется с помощью динамического импорта --btw, если вы удаляете динамическую часть, это не приводит к изменению результата / ошибки).

В nextjs8 это работало нормально, и только состояние Template было перерисованос правильными изменениями ... но в nextjs9 каждый раз, когда состояние изменяется из-за избыточности, вся страница снова перерисовывается, включая вызов getInitialProps ...

Есть идеи?

...