Published on

クイックスタート - New React Docs (日本語翻訳)

Authors

:::note warn 公式の日本語訳版が出たので、本記事は非推奨とします。 https://ja.react.dev/ :::

:::note 本記事はReact公式サイトのQuick Startを翻訳したものですが、非公式の日本語ドキュメントです。 :::

ようこそ、Reactドキュメントへ!このページでは日常的に使うことになるReactの概念の80%を紹介します。

学べること

  • コンポーネントの作成とネストする方法
  • マークアップとスタイルの追加方法
  • データの表示方法
  • 条件とリストのレンダー方法
  • イベントと画面の更新に反応する方法
  • コンポーネント間のデータの受け渡し方法

コンポーネントの作り方とネストさせる方法

Reactアプリはコンポーネントから作られます。一つのコンポーネントは独自のロジックや表示を持ったUI(ユーザーインターフェース)の一部です。コンポーネントはボタンぐらいの小ささ、もしくはページ全体のぐらいの大きさになることができます。

Reactコンポーネントはマークアップを返すJavaScriptの関数です。

function MyButton() {
  return (
    <button>I'm a button</button>
  );
}

MyButtonを宣言しているときに、MyButtonを他のコンポーネントに入れてネストさせることができます。

export default function MyApp() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <MyButton />
    </div>
  );
}

<MyButton />はアッパーケースであることに気をつけましょう。アッパーケースがReactコンポーネントであることを知る方法となります。Reactコンポーネントの命名は必ずアッパーケースで、HTMLタグはローワーケースでなければなりません。

この結果を見てください。

https://codesandbox.io/embed/peaceful-meninsky-ieh8uf?fontsize=14&hidenavigation=1&module=%2FApp.js&theme=dark

export defaultは、ファイルの中でメインコンポーネントであることを定義するキーワードです。もしJavaScriptの構文に詳しくなければ、MDNjavascript.infoがいいリファレンスになります。

JSXを使ったマークアップの書き方

上で見たマークアップ構文はJSXと呼ばれています。JSXは1つの選択肢ですが、利便性の点で多くのReactプロジェクトではJSXを使うことが多いです。私たちがローカル開発で推奨するもの全ては、JSXを使えるようにサポートしています。

JSXはHTMLよりも厳密です。<br />のように閉じタグにしなければなりません。また、コンポーネントは複数のJSXタグを返すことができません。<div>...</div>もしくは<>...</>の中に複数のJSXを入れる必要があります。

function AboutPage() {
  return (
    <>
      <h1>About</h1>
      <p>Hello there.<br />How do you do?</p>
    </>
  );
}

もし多くのHTMLをJSXに変換したいのであれば、online converterを使うことができます。

スタイルの追加

Reactでは、CSSのクラスをclassNameで定義します。HTMLのclass属性と同じような方法で実装することができます。

<img className="avatar" />

分けたCSSファイルでスタイルを書くときは、このようになります。

/* In your CSS */
.avatar {
  border-radius: 50%;
}

Reactは、CSSファイルの追加方法を定めていません。最もシンプルな方法だと、HTMLにlinkタグを追加する方法があります。もし、ビルドツールやフレームワークを使っているのであれば、各々のドキュメントを参照し、プロジェクトにCSSファイルを追加する方法を学んでください。

データの表示方法

JSXはマークアップをJavaScriptの中に入れることができます。コードから変数を埋め込み、ユーザーへ表示するために、中括弧を使うとJavaScriptの中にエスケープバックさせることができます。例えば、user.nameはこのように表示します。

return (
  <h1>
    {user.name}
  </h1>
);

また、JSXの属性からJavaScript内でエスケープすることもできますが、クウォートの代わりに中括弧を使う必要があります。例えば、className="avatar"はCSSクラスとして"avatar"文字列を渡していますが、src={user.imageUrl}はJavaScriptのuser.imageUrl変数を読み出し、src属性に値を渡しています。

return (
  <img
    className="avatar"
    src={user.imageUrl}
  />
);

さらに複雑な構文をJSXの中括弧に入れることができます。例えば、文字列結合はこのようになります。

https://codesandbox.io/embed/serene-curie-15oriv?fontsize=14&hidenavigation=1&module=%2FApp.js&theme=dark

上の例で、style={{}}は特別な構文ではないですが、一般的な{}オブジェクトがstyle={ }の中括弧に入っています。スタイルがJavaScriptの変数に依存するときに、style属性を使うことができます。

条件付きレンダリング

Reactにおいて、条件を実装するための特別な構文はありません。代わりに、一般的なJavaScriptのコードを実装するときと同じように実装できます。例えば、条件分岐でJSXを含めるためにif文を使うことができます。

let content;
if (isLoggedIn) {
  content = <AdminPanel />;
} else {
  content = <LoginForm />;
}
return (
  <div>
    {content}
  </div>
);

よりコンパクトなコードの方がよければ、三項演算子を使うことができます。ifとは異なり、JSX内部で動作します。

<div>
  {isLoggedIn ? (
    <AdminPanel />
  ) : (
    <LoginForm />
  )}
</div>

elseの分岐が必要ないときは、&&を使った構文で短くできます。

<div>
  {isLoggedIn && <AdminPanel />}
</div>

これらの方法はすべて、属性を条件付きで指定する場合にも有効です。JavaScriptの構文に慣れていない方は、まずif...elseを常に使うところから始めるとよいでしょう。

配列のレンダリング

コンポーネントの配列をレンダーするために、forループmap()関数のようなJavaScriptの機能を使うことができます。

例えば、productsの配列を宣言します。

const products = [
  { title: 'Cabbage', id: 1 },
  { title: 'Garlic', id: 2 },
  { title: 'Apple', id: 3 },
];

コンポーネント内で、products配列を<li>アイテムの配列に変換するためには、map()関数を使います。

const listItems = products.map(product =>
  <li key={product.id}>
    {product.title}
  </li>
);

return (
  <ul>{listItems}</ul>
);

<li>key属性を持っていることに注目してください。リストの各アイテムは、シブリング間でアイテム一意に識別する文字列または数値を渡す必要があります。通常、キーはデータベースIDのようなデータから取得する必要があります。Reactは、アイテムを追加、削除、並べ替えしたことを知るためにキーを使用します。

https://codesandbox.io/embed/xenodochial-bell-xtczu1?fontsize=14&hidenavigation=1&module=%2FApp.js&theme=dark

イベント反応

コンポーネント内でイベントハンドラーの関数を宣言することで、イベントに応答することができます。

function MyButton() {
  function handleClick() {
    alert('You clicked me!');
  }

  return (
    <button onClick={handleClick}>
      Click me
    </button>
  );
}

onClick={handleClick}では、最後に丸括弧を付けていないことに注目してください!イベントハンドラーの関数を呼び出さずに、関数を渡すだけで十分です。ボタンを押すときにイベントハンドラーは呼び出されます。

画面の更新

コンポーネントに情報を持たせて表示させたいことがよくあります。例えば、ボタンがクリックされた回数を数えたいということがあるでしょう。実現するには、コンポーネントにstateを追加します。

はじめに、ReactからuseStateをインポートします。

import { useState } from 'react';

すると、状態変数をコンポーネントの中で宣言することができます。

function MyButton() {
  const [count, setCount] = useState(0);

useStateから、現在の状態変数(count)とcountを更新させる関数(setCount)の2つを取得しようとしています。どんな名前でも与えることができますが、[something, setSomething]のように実装することが慣習です。

最初にボタンが表示されるときは、useState0を渡しているためcount0になります。stateを変えたいときは、setCountを呼び出し新しい値を渡します。ボタンをクリックするとカウンターを増加させるにはこのように実装します。

function MyButton() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      Clicked {count} times
    </button>
  );
}

Reactが一度コンポーネント関数を呼び出すとします。このとき、count1になります。そして2になり1ずつ増えていきます。同じコンポーネントを複数レンダーする場合は、それぞれが独立した状態変数になります。分けたボタンをどちらもクリックしてみましょう。

https://codesandbox.io/embed/elated-vaughan-1ghtss?fontsize=14&hidenavigation=1&module=%2FApp.js&theme=dark

各々のボタンが自分のcount状態を保持し、他のボタンには影響を与えていないことに注意してください。

フックスの使い方

useで始まる関数はフックスと呼ばれます。useStateはReactが提供する組み込みのフックです。APIリファレンスで他の組み込まれているフックスを見つけることができます。既存のフックスを組み合わせて自作のフックスを作成することも可能です。

フックスは他の関数よりも制約が多いです。フックスはコンポーネント(または他のHook)の先頭だけで呼び出すことができます。useStateを条件やループの中で使いたい場合は、新しいコンポーネントに切り出してください。

コンポーネント間のデータ共有

先ほどの例では、それぞれのMyButtonが自分のcountを持っており、それぞれのボタンがクリックすることができ、クリックしたボタンのcountのみが変化しました。

スクリーンショット 2023-03-28 0.41.35.png

しかし、どちらもデータを共有し合い同期をするコンポーネントが必要となることがよくあります。

両方のMyButtonコンポーネントが同じカウントを表示し同期するには、個々のボタンの状態を「上へ」移動させ、すべてのボタンを含む最も近いコンポーネントに移動する必要があります。

MyAppでの例です。

スクリーンショット 2023-03-28 0.47.02.png

これで、どちらともボタンをクリックするとき、MyAppの中のcountが変化し、MyButtonのどのカウントも変化することになります。これをコードで表現すると、次のようになります。

まず、MyButtonからMyAppに状態を移動させます。

export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Counters that update separately</h1>
      <MyButton />
      <MyButton />
    </div>
  );
}

function MyButton() {
  // ... we're moving code from here ...
}

そして、MyAppから各MyButtonへ、共有のクリックハンドラーと一緒に状態を渡します。上記で<img>のような組み込みタグで行ったように、JSXの中括弧を使ってMyButtonに情報を渡すことができます。

export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Counters that update together</h1>
      <MyButton count={count} onClick={handleClick} />
      <MyButton count={count} onClick={handleClick} />
    </div>
  );
}

このように渡している情報のことをpropsと呼びます。このMyAppコンポーネントはcount状態とhandleClickイベントハンドラーを含み、その両方を各ボタンにpropsとして渡しています。

最後に、親コンポーネントから受け取ったpropsを読み込めるようにMyButtonを変更します。

function MyButton({ count, onClick }) {
  return (
    <button onClick={onClick}>
      Clicked {count} times
    </button>
  );
}

ボタンをクリックするとき、onClickハンドラーが発火します。各ボタンのonClickpropはMyApp内のhandleClick関数に設定されたので、MyApp内のコードが実行されます。そのコードではcount状態変数をインクリメントするsetCount(count + 1)を呼び出します。新しいcountの値は、各ボタンにpropとして渡されるので、すべてのボタンに新しい値が表示されます。これを「状態を上に上げる」と言います。状態を上に上げることで、コンポーネント間で状態を共有させられます。

https://codesandbox.io/embed/keen-hertz-sqqsbh?fontsize=14&hidenavigation=1&module=%2FApp.js&theme=dark

次のステップ

ここまでで、Reactを実装するための基本を知ることができました! ここで学んだことを実践に活かすためにチュートリアルをチェックし、Reactで初めてのミニアプリを作ってみましょう。