個人的な備忘録です。
やりたいこと
- 特定の遷移元からしか、ページを表示できないようにしたい
- vue-router のように、「from」の情報を取得したい
- userRouter には遷移元の情報がない
- document.referrer では正確な情報が取得できない
環境
- Next: 11.1.3
- React: 17.0.2
パターン1:Contextを使用したパターン
hooks/historyContext.ts
import { createContext } from 'react';
export const HistoryContext = createContext<string[]>(['', '']);
pages/_app.tsx
import { useEffect, useState } from 'react';
import { HistoryContext } from 'hooks';
import type { AppProps } from 'next/app';
import { useRouter } from 'next/router';
const MyApp = ({ Component, pageProps }: AppProps) => {
const router = useRouter();
const [history, setHistory] = useState([router.asPath, '']);
useEffect(() => {
setHistory([router.asPath, history[0]]);
}, [router.asPath]);
return (
<HistoryContext.Provider value={history}>
<Component {...pageProps} />
</HistoryContext.Provider>
);
};
export default MyApp;
component
import { useContext, useEffect } from 'react';
import { useRouter } from 'next/router';
import { HistoryContext } from 'hooks/historyContext';
export const Component = () => {
const history = useContext(HistoryContext);
const router = useRouter();
useEffect(() => {
// 特定のページから遷移してきたか特定
const isFromHoge = history[0].includes('hoge');
// 特定のページから遷移していなければ、強制的に別のページへ飛ばす
if (!isFromHoge) {
router.replace('/foo');
}
}, []);
return (
<></>
)
};
パターン2:SSRを使用したパターン
pages/hoge.ts
import { GetServerSideProps } from 'next';
import { useRouter } from 'next/router';
interface Props {
referer?: string;
}
const Component = ({ referer }: Props) => {
const router = useRouter();
return <></>;
};
export const getServerSideProps: GetServerSideProps = async (context) => {
// あれば fetch
// context の中に遷移元の情報がある
const referer = context.req.headers.referer;
return { props: { referer } };
};
export default Component;
参考