目次
背景
CakePHP4とReactで開発しているのですが、Browser Routerを使うとリロードしてしまったときにエラーが出てしまうのでHash Routerを使っています。ナビゲーションバーは以下のようにmaterial UIというライブラリで作成しているのですが、以下のような問題が起きていました。
ホーム画面以外のページ(画面A)でページ更新を行うと、ページ自体は画面Aが表示されているにも関わらず、Material UIのTabsが初期化されてホーム画面を指し示してしまう
例えば、URLがlocalhost/#/profileを示している時にリロードすると、ページ自体はプロフィールページが表示されているのにTabsではHomeが選択された状態で表示されるということです。
対処法
結論から言うと、現在どのページが選択されているかという設定値は<Tabs>コンポーネントのvalueというプロパティで制御されているので、コンポーネントの読み込み時にハッシュを拾ってvalueを変更する関数を書きます。下記の例ではHookを利用しているのでuseEffectで実施しています。Hookを利用しない場合は、componentDidMount()で行えば動くでしょう。
valueは整数値で0、1、2、…を入力します。
コード例
import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import { makeStyles } from '@material-ui/core/styles';
import { AppBar, Tabs, Tab, Toolbar} from '@material-ui/core';
const NavBar = () => {
const [value, setValue] = useState(0);
const handleChange = (event, value) => {
setValue(value);
}
const hashMap = {
'#/': 0,
'#/weathers': 1,
'#/profile': 2,
};
useEffect(() => {
const hash = location.hash;
setValue(hashMap[hash]);
});
return (
<AppBar position="static">
<Toolbar>
<Tabs value={value} onChange={handleChange}>
<Tab icon={<HomeIcon />} label="HOME" component={Link} to="/" />
<Tab icon={<BarChartIcon />} label="HOME" component={Link} to="/weathers" />
<Tab icon={<PersonIcon />} label="HOME" component={Link} to="/profile" />
</Tabs>
</Toolbar>
</AppBar>
);
}
このように書くと、NavBarコンポーネントがマウントされたときにuseEffect()が実行されて、URLのハッシュ値を拾いvalueが変更されます。そのため、Tabsのselectedも変更されました。