RemixのSPAモードでNavLinkが上手く動かない
ヘッダーのナビゲーション部分で各ページに移動するとリンクにアンダーラインが付くようにしていて問題が…。
yarn run buildでSPAモードで出力したあと動作をチェックしてみると、インデックスページから各ページに移動した際はアンダーラインが付くが、直接各ページを開くとアンダーラインが付かないことに気づいた…。
考えてみるとSPAで一度静的ページに出力するので、出来上がりはindex.htmlのみだ。内部ではインデックスページにいる状態で出力しているので、各ページを直接開いてもNavLinkがURLパスを判別できていないのかもしれない。
ちなみにmod_rewriteで下記のようにリライト設定している。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.html [L]
たぶんこの問題なのかもしれない。
https://github.com/remix-run/react-router/issues/13010
ということで、微妙な感じもするが下記のようにuseEffectでナビゲーションの状態を保持してアクティブかどうか判定するようにして対応。
type NavLinkStatus = {
to: string;
isActive: boolean;
};
const location = useLocation();
const [navLinkStatus, setNavLinkStatus] = useState<NavLinkStatus[]>([]);
useEffect(() => {
const navState = navLinks.reduce((acc, link) => {
acc.push({ to: link.to, isActive: link.to === location.pathname });
return acc;
}, [] as NavLinkStatus[]);
setNavLinkStatus(navState);
}, [location.pathname]);
<NavLink
key={index}
to={link.to}
className={() => {
const fixedActive = navLinkStatus.find((status) => status.to === link.to)?.isActive;
return fixedActive ? 'border-gray-800' : 'border-transparent';
}}
>
{link.name}
</NavLink>
https://github.com/pontago/greenstudio-web/blob/develop/app/components/layout/Header.tsx