Следующий JS код внутри getInitialProps не выполняется после перезагрузки страницы - PullRequest
0 голосов
/ 08 апреля 2020

Я интегрирую Next JS в свое приложение React. Я сталкиваюсь с проблемой: при перезагрузке страницы или открытии прямой ссылки (например, somehostname.com/clients) мой getInitialProps не выполняется, но если я открываю эту страницу, используя <Link> из next/link, она работает хорошо. Я не очень понимаю, почему это происходит и как это исправить. Я уже задавал подобные вопросы, но не нашел решения, которое могло бы подойти для меня.

Код страницы клиента:

import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { ClientsTable } from '../../src/components/ui/tables/client-table';
import AddIcon from '@material-ui/icons/Add';
import Fab from '@material-ui/core/Fab';
import { AddClientModal } from '../../src/components/ui/modals/add-client-modal';
import CircularProgress from '@material-ui/core/CircularProgress';
import { Alert } from '../../src/components/ui/alert';
import { Color } from '@material-ui/lab/Alert';
import { AppState } from '../../src/store/types';
import { thunkAddClient, thunkGetClients } from '../../src/store/thunks/clients';
import { SnackbarOrigin } from '@material-ui/core';
import { IClientsState } from '../../src/store/reducers/clients';
import { NextPage } from 'next';
import { ReduxNextPageContext } from '../index';
import { PageLayout } from '../../src/components/ui/page-layout';

const Clients: NextPage = () => {
  const [addClientModalOpened, setAddClientModalOpened] = useState<boolean>(false);
  const [alertType, setAlertType] = useState<Color>('error');
  const [showAlert, setAlertShow] = useState<boolean>(false);
  const alertOrigin: SnackbarOrigin = { vertical: 'top', horizontal: 'center' };

  const dispatch = useDispatch();
  const { clients, isLoading, hasError, message, success } = useSelector<AppState, IClientsState>(state => state.clients);

  useEffect(() => {
    if (success) {
      handleAddModalClose();
    }
  }, [success]);

  useEffect(() => {
    checkAlert();
  }, [hasError, success, isLoading]);

  function handleAddModalClose(): void {
    setAddClientModalOpened(false);
  }

  function handleAddClient(newClientName: string): void {
    dispatch(thunkAddClient(newClientName));
  }

  function checkAlert() {
    if (!isLoading && hasError) {
      setAlertType('error');
      setAlertShow(true);
    } else if (!isLoading && success) {
      setAlertType('success');
      setAlertShow(true);
    } else {
      setAlertShow(false);
    }
  }

  return (
    <PageLayout>
      <div className='clients'>
        <h1>Clients</h1>

        <div className='clients__add'>
          <div className='clients__add-text'>
            Add client
          </div>
          <Fab color='primary' aria-label='add' size='medium' onClick={() => setAddClientModalOpened(true)}>
            <AddIcon/>
          </Fab>

          <AddClientModal
            opened={addClientModalOpened}
            handleClose={handleAddModalClose}
            handleAddClient={handleAddClient}
            error={message}
          />
        </div>

        <Alert
          open={showAlert}
          message={message}
          type={alertType}
          origin={alertOrigin}
          autoHideDuration={success ? 2500 : null}
        />

        {isLoading && <CircularProgress/>}

        {!isLoading && <ClientsTable clients={clients}/>}

      </div>
    </PageLayout>
  );
};

Clients.getInitialProps = async ({ store }: ReduxNextPageContext) => {
  await store.dispatch(thunkGetClients());
  return {};
};

export default Clients;

thunkGetClients ()

export function thunkGetClients(): AppThunk {
  return async function(dispatch) {
    const reqPayload: IFetchParams = {
      method: 'GET',
      url: '/clients'
    };

    try {
      dispatch(requestAction());

      const { clients } = await fetchData(reqPayload);

      console.log(clients);

      dispatch(getClientsSuccessAction(clients));

    } catch (error) {
      dispatch(requestFailedAction(error.message));
    }
  };
}

_app.tsx code

import React from 'react';
import App, { AppContext, AppInitialProps } from 'next/app';

import withRedux from 'next-redux-wrapper';
import { Provider } from 'react-redux';
import { makeStore } from '../../src/store';
import { Store } from 'redux';

import '../../src/sass/app.scss';
import { ThunkDispatch } from 'redux-thunk';

export interface AppStore extends Store {
  dispatch: ThunkDispatch<any, any, any>;
}

export interface MyAppProps extends AppInitialProps {
  store: AppStore;
}

export default withRedux(makeStore)(
  class MyApp extends App<MyAppProps> {
    static async getInitialProps({
                                   Component,
                                   ctx
                                 }: AppContext): Promise<AppInitialProps> {
      const pageProps = Component.getInitialProps
        ? await Component.getInitialProps(ctx)
        : {};

      return { pageProps };
    }

    render() {
      const { Component, pageProps, store } = this.props;

      return (
        <>
          <Provider store={store}>
            <Component {...pageProps} />
          </Provider>
        </>
      );
    }
  }
);

Нужны ваши советы и помощь. К сожалению, я не смог найти решение самостоятельно.

1 Ответ

1 голос
/ 09 апреля 2020

Так работает Next. js работает, он запускается getInitialProps при первой загрузке страницы (перезагрузка или внешняя ссылка) на сервере и на остальных страницах, по которым осуществляется переход с помощью Link он будет запускать этот метод на клиенте .

Причина этого заключается в том, чтобы сайты Next. js имели "нативную" версию SEO.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...