92
125

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 3 years have passed since last update.

社内でReactの勉強会をした時に作成した、Reactの基本となる用語や考え方をついて紹介します。Reactに興味がある方に、少しでも多くの人にReactについて慣れ親しんでもらえると嬉しいです。

前提事項

  • React 16.8から導入されたhooksを利用した記法に則って記載しております
  • JavaScript(ES6)の構文をベースに記載をしております

アロー関数

ES6から使えるようになった記法です。下記のように関数を宣言することができます

// 通常の記法
fuction hogehoge() {
}

// アロー関数を使った関数宣言
const hogehoge = () => {
}

import

他のモジュールをimportすることができます。reactでは一般的にnpm経由でインストールしたファイルを読み込んで利用します。

import React from 'react';
import ReactDOM from 'react-dom';

Reactとは?

Reactとは、ユーザインターフェイスを作るためのJavaScriptのライブラリです。(よく間違われますが、フレームワークではないそうです。)

UIをコンポーネント(部品)と呼ばれる単位で作成するのが特徴で、この組み合わせで複雑なUIを柔軟に構成することができます。React要素と呼ばれる仮想DOMを生成、これをもとにレンダリングをします。

ReactでHello World!

下記のように書くことができます。

HTMLファイル

<div id="root"></div>

JSファイル

import React from 'react';
import ReactDOM from 'react-dom';

const element = <div>Hello, world</div>;
ReactDOM.render(
  element,
  document.getElementById('root')
);

なんか見慣れない構文が出てきましたね。。。
1つずつ解説していきます!

JSXとは?

上記でelementに格納された値は、JSXと呼ばれ、React要素を簡単に記述することのできる方法です。これにより、htmlをJsのなかに書いているような感覚で記述ができます。

実際にはReact.createElementに変換されていますので下記の文面は同義です。基本的にはJSXで書いていけば大丈夫です。

// JSX
const yesJsx = <div>Hello, world</div>;

// React.createElement
const noJsx = React.createElement('div', null, 'Hello World');

JSX なしで React を使う – React

JSXで変数展開

JSX内では中括弧{}で囲むことで変数を展開することができます

const displayText = 'HelloWorld';
const HelloWorld = () => {
  return (
    <div>
      <p>{ displayText }</p>
    </div>
  )
}

NGなJSXの例

JSXは基本的には一つのエレメントしか返すことができません。下記のようにreturnするエレメントが2つ以上あるとエラーとなります。

// エラーが出ます
import React from 'react';

const HelloWorld = () => {
  return (
    <div>
      <p>HelloWorld</p>
    </div>
    <div>
      <p>HelloWorld</p>
    </div>
  )
}

ただ、divのなかに囲ってあげると正常に動作します。

import React from 'react';

const HelloWorld = () => {
  return (
    <div>
      <div>
        <p>HelloWorld</p>
      </div>
      <div>
        <p>HelloWorld</p>
      </div>
    </div>
  )
}

複数の要素を返すことはできないのか?

実は、複数の要素を返す方法として**「Fragment(フラグメント)」**というものがあります。

ここではあまり詳しく言及はしませんが、実施に書いていると、複数の要素を返したい場合も出てくるので、その際はこの記法を活用することで解消することができます!
フラグメント – React

P.S @uitspitss さん、コメントいただきありがとうございます!

コンポーネントとは?

コンポーネントとは、UIの構成要素のことです。この部品を組み合わせて1つのページを作成していきます。実際はコンポーネント単位でjsファイルを作成し、importして呼び出すことが多いですが、今回はあまり気にせずに書いていきます。

例として、公式のチュートリアルにある三目ゲーム(⭕️❌ゲーム)のUIを例に説明します。下記の画像をご覧ください。
スクリーンショット 2020-09-30 19.50.21.png

このようなUIがあったとして、Reactではこれを3つのコンポーネントに分けて考えます。1つはページ全体のGame、盤面を表すBoard、最後にマス目1つ1つを表すSquareです。Squareに関しては9つ存在することになります。
スクリーンショット 2020-09-30 19.59.56.png

このような単位のことをコンポーネントと呼びます。コードに表すと下記のような感じです。

// 三目並べゲームのコンポーネント
import React from 'react';

// 盤面のマス1つ1つのコンポーネント
const Square = (props) => {
  // 省略
}

// 盤面全体のコンポーネント
const Board = () => {
  // 省略
}

// ページ全体のコンポーネント
const Game = () => {
  // 省略
}

Tic Tac Toe
チュートリアル:React の導入 – React

stateとpropsについて

コンポーネントで使われる概念のうち、最初に覚えておきたいのがstateとpropsです。

  • stateはコンポーネントの内部で制御される値のことです
  • propsは親(呼び出し元)コンポーネントから受け取る値のことで基本読み取り専用になります

ちなみにpropsはpropertiesを略したものです。

この2つの値をコンポーネント間で受け渡す事で、複雑なUIを制御することができます

state

stateはコンポーネントの内部で制御される値のことです。そのため基本的には他のコンポーネントから制御できません。

また、stateが更新されると同時にコンポーネントの値が再レンダーされます。下記のコードでは、useStateというAPIを使う事でstateを管理しています。

下記の例ではBoard(盤面)コンポーネントにて9つのsquares(マス)の状態と、プレイヤーの順番の状態をstateで管理しています。

import React, { useState } from 'react'; // hooks

const Board = () => {
  // コンストラクタ
  const [squares, setSquares] = useState(Array(9).fill(null));
  const [xIsNext, setXIsNext] = useState(true);

  // 以下省略 
}

propsを子コンポーネントに渡す

BoardコンポーネントからSquareコンポーネントを呼び出すときにvalueとonclickにpropsを渡しています。この時、変数だけでなく関数を渡す事もできます。

const Board = () => {
  const squares = [0, 1, 2]
  const handleClick = (i) {
    // 省略
  }
  return (
    <Square value={squares} onClick={() => handleClick(i)}/>
  );
}

propsを受け取り、参照する

Squareコンポーネントは引数としてpropsを受け取ります。

props自体はオブジェクト構造となっており、props.xxxという記法で呼び出すことができます。下記の例ではvalueの中身の表示と、親コンポーネントの関数の実行をしています

const Square = (props) => {
  return (
    <button className="square" onClick={() => props.onClick()}>
      {props.value}
    </button>
  ); 
}

ご参考 〜Reactで書く三目並べ(⭕️❌ゲーム)のコード〜

最終的なコードは下記になります。

公式のチュートリアル:React の導入 – Reactにも書かれているゲームのコードです。公式チュートリアルではコンポーネントの記法が少し古いため、Hooksで書き換えております。

import React, { useState } from 'react';
import ReactDOM from 'react-dom';

// controlled component
const Square = (props) => {
  return (
    <button className="square" onClick={() => props.onClick()}>
      {props.value}
    </button>
  ); 
}

const Board = () => {
  const [squares, setSquares] = useState(Array(9).fill(null));
  const [xIsNext, setXIsNext] = useState(true);

  const handleClick = (i) => {
    const cloneSquares = squares.slice();
    if (calculateWinner(cloneSquares) || cloneSquares[i]) {
      return;
    }
    cloneSquares[i] = xIsNext ? 'X' : 'O';
    setSquares(cloneSquares);
    setXIsNext(!xIsNext);
  }

  const renderSquare = (i) => {
    return (
      <Square
        value={squares[i]}
        onClick={() => handleClick(i)}
      />
    );
  }

  const winner = calculateWinner(squares);
  
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <div>
      <div className="status">{status}</div>
      <div className="board-row">
        {renderSquare(0)}
        {renderSquare(1)}
        {renderSquare(2)}
      </div>
      <div className="board-row">
        {renderSquare(3)}
        {renderSquare(4)}
        {renderSquare(5)}
      </div>
      <div className="board-row">
        {renderSquare(6)}
        {renderSquare(7)}
        {renderSquare(8)}
      </div>
    </div>
  );
}

const Game = () => {
  return (
    <div className="game">
      <div className="game-board">
        <Board />
      </div>
      <div className="game-info">
        <div>{/* status */}</div>
        <ol>{/* TODO */}</ol>
      </div>
    </div>
  );
}

const calculateWinner = squares => {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}

// ========================================

ReactDOM.render(
  <Game />,
  document.getElementById('root')
);

おさらい

  • ReactはJavascriptのライブラリである
  • Javascript(ES6)の構文がベースとなっている
  • JSXという記法を使った仮想DOMを記述することができる
  • コンポーネントベースでUIを生成する
  • コンポーネントではstateとpropsを駆使して柔軟なUIを作成することができる
  • stateはコンポーネント内部で制御する値のこと(外部から変更はできない)
  • propsは基本参照のみだが、親コンポーネントの関数を渡すことができる

まとめ

少しでもReactに関心を持ってくだされば幸いです!

参考リンク

92
125
2

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
92
125

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?