29
37

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ReactJS入門@ES6:ReactRouter編

Last updated at Posted at 2016-02-04

対象者:私を含むReact初心者
前:ReactJS入門@ES6:コンポーネント編
次:ReactJS入門@ES6:Redux編


前提

ReactRouterのbrowserHistoryを使用する。

追記:下記mod_rewriteの設定は私の環境では必要ありませんでした。
逆に必須だったのは、<base>の設定でした。

index.htmlにリクエストを投げるためApacheのmod_rewriteモジュールを使用。

<ifModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule (.*) index.html [L,QSA]
</ifModule>

私の環境ではHTMLにベースの指定が必要だった。

<body>
  <base href="/" />
</body>

サンプル概要

作成するサンプルの概要。
トップ画面 ▶ ユーザ画面 ▶ アイテム画面 というシンプルな構成。

画面 説明 URL
トップ ヘッダを表示 http://ex/
ユーザ 指定したユーザ情報を表示 http://ex/user/{userName}
アイテム 指定したユーザのアイテムを表示 http://ex/user/{userName}/item/{itemId}

追記:書き忘れていましたが、
今回はURLパラメータを処理するサンプルとなっているので、
{userName}や{itemID}の部分をブラウザのURL入力欄で適当に書き換えても動作します。


ルーティングの設定

実際のコードとは異なるが、今回は雰囲気を掴みやすくするために、
ルーティングの設定から記述する。

今回はReactDOM.renderに直接指定している。

ReactDOM.render((
  <Router history={browserHistory}>
    <Route path="/" component={App}>
      <Route path="user/:userName" component={User}>
        <Route path="item/:itemId" component={Item} />
      </Route>
    </Route>
  </Router>
), document.getElementById('wrapper'));

コンポーネント作成

今回は1コンポーネント1画面という前提で作成。
画面移動用のボタンはReactRouterのLinkクラスで描画する。

<Link to={'/sample'} activeClassName="active">Sample</Link>

URLパラメータはthis.props.paramsから取得する。

Appコンポーネントを作成

ルートコンポーネント

class App extends React.Component {
  render() {
    return (
      <div>
        <ul>
          <li><Link to="/" activeClassName="active">Index</Link></li>
          <li><Link to="/user/kinjo" activeClassName="active">User:KINJO</Link></li>
        </ul>
        {this.props.children}
      </div>
    )
  }
}

Userコンポーネントを作成

URLパラメータで指定したuserNameを表示するコンポーネント
文字列中の変数を展開するために、ES6のテンプレートリテラルを使用しています。

class User extends React.Component {
  render() {
    const { userName } = this.props.params;

    return (
      <div className="User">
        <h1>User Name: {userName}</h1>
        <ul>
          <li><Link to={`/user/${userName}/item/1`} activeClassName="active">Item:1</Link></li>
        </ul>
        {this.props.children}
      </div>
    )
  }
}

Itemコンポーネントを作成

URLパラメータで指定したItemIdを表示するコンポーネント

class Item extends React.Component {
  render() {
    const { userName, itemId } = this.props.params;
    return (
      <div className="Item">
        <h2>User Name: {userName}</h2>
        <h2>Item ID: {itemId}</h2>
      </div>
    )
  }
}

親コンポーネントの役目は子コンポーネントを表示すること

ユーザ画面(User)を表示しているのは、
親コンポーネント(App)の{this.props.children}であり、
アイテム画面(Item)を表示しているのは、
親コンポーネント(User)の{this.props.children}である。


動的な画面遷移を行う

contextTypesでrouterを設定することにより、
this.context.router.push();が使えるようになる。

EX :

class Item extends React.Component {
  static contextTypes = {
    router: React.PropTypes.object.isRequired
  };
  componentWillMount() {
    //this.context.router.push('/user/unknown');
  }
  render() {
    const { userName, itemId } = this.props.params;
    return (
      <div className="Item">
        <h2>User Name: {userName}</h2>
        <h2>Item Id: {itemId}</h2>
      </div>
    )
  }
}
29
37
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
37

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?