reactjs - getInitialProps 中的下一个 JS 代码在页面重新加载后不执行
问题描述
我正在将 NextJS 集成到我的 React 应用程序中。我遇到了一个问题,在页面重新加载或打开直接链接(例如 somehostname.com/clients)时我没有执行,但是如果我使用from它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 代码
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>
</>
);
}
}
);
寻求您的建议和帮助。不幸的是,我自己找不到解决方案。
解决方案
这就是 Next.js 的工作方式,它在服务器getInitialProps
中的第一个页面加载(重新加载或外部链接)时运行,并且使用它导航到的其余页面将在客户端上运行此方法。Link
这样做的原因是允许 Next.js 网站具有“本机”SEO 版本。
推荐阅读
- excel - 有没有办法在 Excel 中生成 TeamViewer 密码?
- javascript - Lazysizes bgset 在调整大小时不改变图像
- typescript - 使用异步等待的顺序函数调用问题
- javascript - 需要不显示或不生成图表标记
- reactjs - axios.post 请求得到 404
- r - sf map 使用 inter_join 添加缺失值
- java - JSONParser:IOException:无法解析主机“我的主机地址”:没有与主机名关联的地址
- react-native - 我们可以将 ag-grid 数据网格与反应本机应用程序集成吗
- r - Rscript -e 在从 OSX SSH 时打破空格,但不是从 linux
- apache - 如何在保留 POST 数据的同时重写 URL?