抹桥的博客
Language
Home
Archive
About
GitHub
Language
主题色
250
1059 文字
5 分
React Router 初挑戦

react-routerは、Reactで構築されたシングルページアプリケーションでルーティング機能を簡単に実装できる、シンプルかつ強力なAPIを提供します。 まず、簡単な例を見てみましょう。

import React from "react";
import { findDOMNode, render } from "react-dom";
import { Link, Route, Router } from "react-router";

let Page1 = React.createClass({
  render() {
    return (
      <div>
        <h1>Page1</h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit.
        Ab accusantium animi dicta dignissimos earum eos esse impedit ipsum iste
        laboriosam numquam odio perspiciatis porro, quas sequi tempore vero
        vitae voluptates?
      </div>
    );
  },
});

let Page2 = React.createClass({
  render() {
    return (
      <div>
        <h1>Page2</h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit.
        Fuga porro voluptas voluptatum. Corporis debitis deleniti, doloremque et
        eum ex id iste magni nobis nostrum quae, reiciendis rem repellendus
        similique tempora.
      </div>
    );
  },
});

let App = React.createClass({
  render() {
    return (
      <div>
        <Link to="/page1">Page1</Link>
        <Link to="/page2">Page2</Link>
      </div>
    );
  },
});

render(
  <Router>
    <Route path="/" component={App}>
      <Route path="page1" component={Page1} />
      <Route path="page2" component={Page2} />
    </Route>
  </Router>,
  document.body,
);

<Link>タグのto属性にパスを定義するだけで、レンダリングされたページでPage1またはPage2のタグをクリックすると、対応するComponentsが表示され、urlもパスに応じて変化します。 このコードを簡単に分析してみましょう。ここでは3つのルートを定義しています。1つはルートディレクトリ、つまり/を指し、もう1つはpage/を、そしてもう1つはpage/2を指しています。 ルートの定義は<Router></Router>で囲む必要があります。 <Route></Route>は、各ルートで定義するパスと、その動作を処理するためのものです。pathはパスを、componentはレンダリングするコンポーネントを示します。また、ルートの動作を制御するためのhandleも提供できます。 次に、ログインをインターセプトする動作をシミュレートしてみましょう。

import React from "react";
import TransitionGroup from "react-addons-transition-group";
import { findDOMNode, render } from "react-dom";
import { History, Link, Route, Router } from "react-router";

require("./index.css");

let goLogin = {
  isLogin: true,
  login() {
    this.isLogin ? this.onChange(false) : this.onChange(true);
    this.isLogin = !this.isLogin;
  },
  onChange() {},
};

let App = React.createClass({
  getInitialState() {
    return {
      login: goLogin.isLogin,
    };
  },
  updateAuth(logged) {
    this.setState({
      login: logged,
    });
  },
  componentWillMount() {
    goLogin.onChange = this.updateAuth;
  },
  render() {
    return (
      <div>
        <nav className="nav">
          {this.state.login ? (
            <Link to="/logout">Log out</Link>
          ) : (
            <Link to="/login">Log in</Link>
          )}
        </nav>
        <ul>
          <li>
            <Link to="/page1" activeClassName="active">
              Page1
            </Link>
          </li>
          <li>
            <Link to="/page2" activeClassName="active">
              Page2
            </Link>
          </li>
        </ul>
        {this.props.children}
      </div>
    );
  },
});
let Login = React.createClass({
  mixins: [History],
  handleClick(event) {
    event.preventDefault();
    goLogin.login();
    var { location } = this.props;
    if (location.state && location.state.nextPathname) {
      this.history.replaceState(null, location.state.nextPathname);
    } else {
      this.history.replaceState(null, "/about");
    }
    console.log(this.history);
  },
  render() {
    return (
      <div>
        <button onClick={this.handleClick}>Login</button>
      </div>
    );
  },
});

let Logout = React.createClass({
  componentDidMount() {
    goLogin.login();
  },
  render() {
    return (
      <div>
        <p>You are now logged out</p>
      </div>
    );
  },
});

let About = React.createClass({
  render() {
    return (
      <div>
        <h1>登录成功</h1>
      </div>
    );
  },
});

let Page1 = React.createClass({
  render() {
    return (
      <div className="page">
        <h1>Page1</h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit.
        Ab accusantium animi dicta dignissimos earum eos esse impedit ipsum iste
        laboriosam numquam odio perspiciatis porro, quas sequi tempore vero
        vitae voluptates?
      </div>
    );
  },
});
let Page2 = React.createClass({
  getInitialState() {
    return {
      className: "pageactive",
    };
  },
  handler() {
    if (this.state.className === "pageactive") {
      this.setState({
        className: "",
      });
    } else {
      this.setState({
        className: "pageactive",
      });
    }
  },
  render() {
    return (
      <div className={`${this.state.className} page`} onClick={this.handler}>
        <h1>Page2</h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit.
        Fuga porro voluptas voluptatum. Corporis debitis deleniti, doloremque et
        eum ex id iste magni nobis nostrum quae, reiciendis rem repellendus
        similique tempora.
      </div>
    );
  },
});

needLogin関数を定義し、ユーザーがログインしているかどうかを判断し、状況に応じて適切なページにリダイレクトします。

function needLogin(nextState, replaceState) {
  if (!goLogin.isLogin) {
    replaceState({ nextPathname: nextState.location.pathname }, "/login");
  }
}

最後に、renderコマンドを実行します。

render(
  <Router>
    <Route path="/" component={App}>
      <Route path="login" component={Login} />
      <Route path="logout" component={Logout} />
      <Route path="about" component={About} />
      <Route path="page1" component={Page1} />
      <Route path="page2" component={Page2} onEnter={needLogin} />
    </Route>
  </Router>,
  document.body,
);

DEMOはこちらをクリック このコードは、以下の機能を実装しています。

  1. ページはデフォルトで未ログイン状態です。
  2. この状態でPage1をクリックすると、Page1の内容が表示されます。
  3. Page2をクリックすると、ページ内容の表示がインターセプトされ、ログインページが表示されます。
  4. loginをクリックすると、Page2の内容が表示され、状態がLogoutに切り替わります。
  5. Logoutをクリックすると、ログアウトします。

このコードでは、page2をクリックすると、まず<Link>タグのto属性がトリガーされ、pathpage2である対応するルートが検索され、その後needLoginイベントがトリガーされます。 needLoginイベントでは、goLogin.isLoginイベントを判断し、未ログインの場合はパスを/loginに置き換えます。 そして、<Route>の中からpath/loginである項目を見つけ、Loginコンポーネントをレンダリングします。 つまり、<Route>内でイベントをリッスンすることで、必要に応じて動的にルーティングアドレスを変更できるということです。

この記事は 2015年10月9日 に公開され、2015年10月9日 に最終更新されました。3650 日が経過しており、内容が古くなっている可能性があります。

React Router 初挑戦
https://blog.kisnows.com/ja-JP/2015/10/09/react-router/
作者
Kisnows
公開日
2015-10-09
ライセンス
CC BY-NC-ND 4.0