We want to hear from you!Take our 2021 Community Survey!
このサイトの更新は終了しました。ja.react.dev へ

React

ユーザインターフェース構築のための JavaScript ライブラリ

宣言的な View

React は、インタラクティブなユーザインターフェイスの作成にともなう苦痛を取り除きます。アプリケーションの各状態に対応するシンプルな View を設計するだけで、React はデータの変更を検知し、関連するコンポーネントだけを効率的に更新、描画します。

宣言的な View を用いてアプリケーションを構築することで、コードはより見通しが立ちやすく、デバッグのしやすいものになります。

コンポーネントベース

自分自身の状態を管理するカプセル化されたコンポーネントをまず作成し、これらを組み合わせることで複雑なユーザインターフェイスを構築します。

コンポーネントのロジックは、Template ではなく JavaScript そのもので書くことができるので、様々なデータをアプリケーション内で簡単に取り回すことができ、かつ DOM に状態を持たせないようにすることができます。

一度学習すれば、どこでも使える

React と組み合わせて使用する技術に制限はありません。React を使って新しい機能を追加する際に、既存のソースコードを書き換える必要はありません。

React は Node を使ったサーバ上でもレンダーできますし、React Native を使うことでモバイルアプリケーションの中でも動きます。


シンプルなコンポーネント

React コンポーネントを作成するには render() メソッドを実装します。このメソッドは、受け取った入力データを元に、表示する内容を返す役割を担当します。次の例では JSX と呼ばれる XML に似た構文を使っています。コンポーネントに渡された入力データを this.props で参照し、render() の中で使用しています。

React を使う際に JSX を必ず使わなくてはいけないわけではありません。 JSX のコンパイルによって生成される生の JavaScript コードを見るには、Babel REPL を参照してください。

Live JSX Editor
class HelloMessage extends React.Component {
  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

root.render(<HelloMessage name="Taylor" />);
Result
Hello Taylor

状態を持つコンポーネント

コンポーネントは、入力されたデータを受け取るだけではなく(受け取ったデータは this.props で参照することができます)コンポーネント独自の内部状態を持つこともできます(これは this.state で参照することができます)。状態が変化した場合には、render() が再度実行され、描画されるマークアップが更新されます。

Live JSX Editor
class Timer extends React.Component {
  constructor(props) {
    super(props);
    this.state = { seconds: 0 };
  }

  tick() {
    this.setState(state => ({
      seconds: state.seconds + 1
    }));
  }

  componentDidMount() {
    this.interval = setInterval(() => this.tick(), 1000);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    return (
      <div>
        Seconds: {this.state.seconds}
      </div>
    );
  }
}

root.render(<Timer />);
Result
Seconds: 2

アプリケーションの実例

propsstate を組み合わせることで、ちょっとした Todo アプリケーションを作ることができます。次の例では state を用いて、現在の Todo リストのアイテムの状態を追跡しています。それからユーザが入力したテキストに関しても state で管理しています。イベントハンドラは、それが書かれた要素内部にレンダーされるように一見思われますが、実際にはこれらのハンドラは集められて、イベントデリゲーションを用いて実装されます。

Live JSX Editor
class TodoApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = { items: [], text: '' };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  render() {
    return (
      <div>
        <h3>TODO</h3>
        <TodoList items={this.state.items} />
        <form onSubmit={this.handleSubmit}>
          <label htmlFor="new-todo">
            What needs to be done?
          </label>
          <input
            id="new-todo"
            onChange={this.handleChange}
            value={this.state.text}
          />
          <button>
            Add #{this.state.items.length + 1}
          </button>
        </form>
      </div>
    );
  }

  handleChange(e) {
    this.setState({ text: e.target.value });
  }

  handleSubmit(e) {
    e.preventDefault();
    if (this.state.text.length === 0) {
      return;
    }
    const newItem = {
      text: this.state.text,
      id: Date.now()
    };
    this.setState(state => ({
      items: state.items.concat(newItem),
      text: ''
    }));
  }
}

class TodoList extends React.Component {
  render() {
    return (
      <ul>
        {this.props.items.map(item => (
          <li key={item.id}>{item.text}</li>
        ))}
      </ul>
    );
  }
}

root.render(<TodoApp />);
Result

TODO

    外部プラグインを使用するコンポーネント

    React は柔軟性が高いので、React 以外のライブラリやフレームワークとやり取りをするためのフックを提供しています。次の例では Markdown の外部ライブラリである remarkable を使用しています。<textarea> に入力された値をリアルタイムに HTML へと変換しています。

    Live JSX Editor
    class MarkdownEditor extends React.Component {
      constructor(props) {
        super(props);
        this.md = new Remarkable();
        this.handleChange = this.handleChange.bind(this);
        this.state = { value: 'Hello, **world**!' };
      }
    
      handleChange(e) {
        this.setState({ value: e.target.value });
      }
    
      getRawMarkup() {
        return { __html: this.md.render(this.state.value) };
      }
    
      render() {
        return (
          <div className="MarkdownEditor">
            <h3>Input</h3>
            <label htmlFor="markdown-content">
              Enter some markdown
            </label>
            <textarea
              id="markdown-content"
              onChange={this.handleChange}
              defaultValue={this.state.value}
            />
            <h3>Output</h3>
            <div
              className="content"
              dangerouslySetInnerHTML={this.getRawMarkup()}
            />
          </div>
        );
      }
    }
    
    root.render(<MarkdownEditor />);
    
    Result

    Input

    Output

    Hello, world!