The source code for this blog is available on GitHub.

Blog.

Reactを学ぶ3(React Router)

Cover Image for Reactを学ぶ3(React Router)

こちらを参考に。 今から始めるReact入門 〜 React Router

作業時間:5時間 経過時間:13時間

パスに応じてデータを受け渡す方法が主だった。

React Routerについて

最上位のimportで各パーツを呼び出している。 Routeタグのcomponent属性に渡している。そして、Linkで遷移したあとに、アクセスのあったパスに応じて、componentを表示する。 exactは完全一致を担っている。ない場合は、部分一致になる。 this.props.childrenでアクセスに応じたcomponentを返すようにしている。

//client.js
import Featured from "./pages/Featured";
import Archives from "./pages/Archives";
import Settings from "./pages/Settings";
const app = document.getElementById('app');

ReactDOM.render(
  <Router>
    <Layout>
      <Route exact path='/' component={Featured}></Route>
      <Route path='/archives/:article' name="archives" component={Archives}></Route>
      <Route path='/settings' name="settings" component={Settings}></Route>
    </Layout>
  </Router>,
app)
//Layout.js
import { Link } from "react-router-dom";
export default class Layout extends React.Component {
  render() {
    return (
      <div>
        {this.props.children}
        <Link to="archives">archives</Link>,
        <Link to="settings">settings</Link>
      </div>
    );
  }
}

historyについて

履歴を残す

withRouterで行っている。 navigate関数のpropsのhistoryオブジェクトのpushで行う。

//Layout.js
import { Link, withRouter } from "react-router-dom";
class Layout extends React.Component {
  navigate() {
    console.log(this.props.history);
    this.props.history.push("/");
  }
  render() {
    return (
      <div>
        ...
        <button class="btn btn-info" onClick={this.navigate.bind(this)}>featured</button>
      </div>
    );
  }
}

export default withRouter(Layout);

履歴を残さない

navigate関数のpropsのhistoryオブジェクトのreplaceで行う。

...
navigate() {
  console.log(this.props.history);
  this.props.history.replace("/");
}
...

URLについて

パラメータ

Route要素のpath属性にコロンを設定すると、propsのparamsからアクセスができる。

//client.js
ReactDOM.render(
  <Router>
    <Layout>
      ...
      <Route exact path="/archives" component={Archives}></Route>
      <Route path="/archives/:article" component={Archives}></Route>
    </Layout>  
  </Router>
)
//Archives.js
export default class Archives extends React.Component {
  render() {
    return (
       <h1>Archives ({this.props.match.params.article})</h1>
    );
  }
}

正規表現を使用する場合、:mode()で行う。 上記の場合、paramsのmodeから参照できる。

//client.js
<Route path="/settings/:mode(main|extra)" component={Settings}></Route>
//Settings.js
export default class Settings extends React.Component {
  render() {
    const type = (this.props.match.params.mode == "extra"? " (for experts)": "");
    return (
       <h1>Settings{type}</h1>
    );
  }
}

クエリストリング

Link要素のto属性にクエリを付与できる。 URLSearchParamsを利用し、query.get('hoge')でクエリの値を参照できる。

//Layout.js
class Layout extends React.Component {
  ...
  render() {
    return (
      <div>
        ...
        <Link to="/archives/some-other-articles?date=yesterday&filter=none" class="btn btn-warning">archives (some other articles)</Link>
        <Link to="/archives?date=today&filter=hot" class="btn btn-danger">archives</Link>
        ...
      </div>
    );
  }
}
//Archives.js
export default class Archives extends React.Component {
  render() {
    const query = new URLSearchParams(this.props.location.search)
    let message
        = (this.props.match.params.article ? this.props.match.params.article + ", ": "")
        + "date=" + query.get("date") + ", filter=" + query.get("filter");
    return (
      <h1>Archives ({message})</h1>
    );
  }
}

アクティブについて

NavLinkを使用すると、該当リンク表示中はactiveClassNameが適用される。

import { NavLink, Link, withRouter } from "react-router-dom";
class Layout extends React.Component {
  render(){
    return (
      <div>
        <NavLink to="/settings/main" class="btn btn-success" activeClassName="btn-danger">settings</NavLink>
      </div>
    )
  }
}

More Stories