★前回の記事
Navbar
を実装して、ナビゲーションリンクを作成します。
ルートパス(Home)へのリンクと、ログインしている場合は、自身のタスク一覧へのリンクを表示します。
リンクは、通常はLink
コンポーネントを使用しますが、ナビゲーションには、Link
のスペシャルバージョンであるNavLink
を利用します。NavLink
を使用すると、現在表示しているページのリンクだけCSSスタイルを変えたい、という要望が簡単に実現できます。
ルートパス(Home)へのリンクの追加
手始めにHomeへのリンクを追加します。activeStyle
を設定して、現在のURLが/
のときに文字の太さと文字色を変えています。
src/components/Navbar.js
import React from 'react' import { NavLink } from 'react-router-dom' let Navbar = () => ( <div> <NavLink exact to='/' activeStyle={{fontWeight: "bold", color: "#DF3A01"}}>Home</NavLink> </div> ) export default Navbar;
動作確認します。http://localhost:3000/users/aaaaa/todos を表示した後、Homeリンクを押します。
URLが/
に変化し、画面もルート(Home)に遷移して、Homeリンクの文字が赤の太字になっています。
ログイン時、自身のtodosへのリンクの追加
ログイン時に、/users/{ユーザID}/todos
へのリンクを表示します。
src/components/Navbar.js
import React from 'react' import { connect } from 'react-redux' import { NavLink } from 'react-router-dom' import PropTypes from 'prop-types' let Navbar = ({uid}) => ( <div> <NavLink exact to='/' activeStyle={{fontWeight: "bold", color: "#DF3A01"}}>Home</NavLink> { uid && <NavLink exact to={`/users/${uid}/todos`} activeStyle={{fontWeight: "bold", color: "#DF3A01"}}>タスクを編集する</NavLink> } </div> ) Navbar.propTypes = { uid: PropTypes.string } const mapStateToProps = state => ( { uid: state.firebase.auth.uid } ) Navbar =connect( mapStateToProps )(Navbar) export default Navbar;
動作確認してみます。
ログアウト時はタスクへのリンクは表示されません。
http://localhost:3000/ を開き、 Homeからタスク一覧へ遷移します。
ルートパスから/users/{ユーザID}/todos
に遷移して、todoComponent
が描画されましたが、NavLink
の表示が変わりません。/users/{ユーザID}/todos
に遷移したときにHome
のスタイルは解除され、タスクを編集する
にactiveStyle
で指定したスタイルが適用されるはずですが。。
NavLinkをconnectと一緒に使用するときは、withRouterを使用する
connectを使用するとスタイルが適用されない件については、 react-router/docs/guides/blocked-updates に記載があります。URLが変更されても、connectで変更が検知されず、下位コンポーネントの再描画がされないことが原因のようです。
この現象を回避するには、connect
をwithRouter
で囲みます。これによって、location
オブジェクトがconnect
にprops
として渡されます。location
オブジェクトはページ遷移のたびに書き換えられるので、connect
で変更が検知されます。これでうまく動きます。
コードを修正します。
src/components/Navbar.js
import { NavLink, withRouter } from 'react-router-dom' // 変更 // 中略 Navbar = withRouter(connect( mapStateToProps )(Navbar)) // 後略
動作確認をします。再び http://localhost:3000/ を開き、 Homeからタスク一覧へ遷移します。
Home画面から/users/{ユーザID}/todos
に遷移したときに、NavLink
のスタイル切り替えも行われました。
以上でナビゲーションリンクが完成しました。
★次回の記事
★目次