react-routerで同じComponentにLinkで遷移したときにstateがリフレッシュされない
まとめ
Route
に異なるkey
を設定する
<Route exact key={'new'} path={'/posts/new'} component={EditPostComponent} /> <Route exact key={'edit'} path={'/posts/:id/edit'} component={EditPostComponent} />
<li>
などでリストを表示したときにkey
を設定してないとwarningが表示されるが、それと同じことが起きていると思えばよい。
https://reactjs.org/docs/lists-and-keys.html#keys
サンプル
コードを貼り付けるとこんな感じ。
import * as React from 'react'; import {Link, Route, Router, Switch, useLocation} from 'react-router-dom'; const MyComponent = (props) => { const current = useLocation().pathname; const next = current == '/a' ? '/b' : '/a'; const [counter, setCounter] = React.useState<number>(0); return ( <> <div> <div>Counter: {counter}</div> <button onClick={() => setCounter(counter + 1)}>Increment</button> </div> <Link to={next}>Current: {current}, Next: {next}</Link> </> ); }; const App: React.FC = () => { const history = require('history').createBrowserHistory; // 同じMyComponentを表示する異なるパスがある return ( <Router history={history()}> <Switch> <Route exact path={'/'} render={() => <Link to={'/a'}>To /a</Link>} /> <Route exact path={'/a'} component={MyComponent} /> <Route exact path={'/b'} component={MyComponent} /> </Switch> </Router> ); };
動かしてみると、パスが変わってもstateが保持されてしまっているのがわかる。 CodePenのとはimportしてたりわずかに違うが、コードとしては同じ。
See the Pen React Router missing key by petitviolet (@petitviolet) on CodePen.
先程のコードのRoute
にkey
を追加してみる。
- <Route exact path={'/a'} component={MyComponent} /> - <Route exact path={'/b'} component={MyComponent} /> + <Route exact key={'a'} path={'/a'} component={MyComponent} /> + <Route exact key={'b'} path={'/b'} component={MyComponent} />
動かしてみると、期待しているように動いているのがわかる。
See the Pen React Router missing key by petitviolet (@petitviolet) on CodePen.