ReactのチュートリアルをTypescriptでやってみる-2

React

Reactを学習することになったのでチュートリアルをやってみようと思う。しかし、チュートリアルはTypescriptではないので、調べながら変更していこうと思う。

前回からのつづき

概要

データをProps経由で渡す

  1. Board.tsxrenderSquareメソッド内で、propsとしてvalueという名前の値をSquareに渡す。
const renderSquare = (i: number) => {
  return <Square value={i} />;
};
  1. Square.tsxでpropsを受け取れるようにする。
// ↓ 追加
type SquareProps = {
  value: number;
};
// ↑ 追加
              // ↓ props: SquareProps を追加
const Square = (props: SquareProps) => {
  return (
    <button className="square">
      {props.value} // ← props.value に変更
    </button>
  );
};

export default Square;

インタラクティブなコンポーネントを作る

  1. Square.tsxにstateを初期化する記述、マス目をクリックしたときの記述をする。
import React from 'react'; // ←追加

type SquareProps = {
  value: number;
};
export type StateType = 'O' | 'X' | null; // ←追加

const Square = (props: SquareProps) => {
// ↓追加
  const [state, setState] = React.useState<StateType>(null);
  const handleClick = () => {
    console.log('click');
    setState('X');
  };
// ↑追加

  return (
    <button
      className="square"
      onClick={handleClick} // 追加
    >
      {props.value}
    </button>
  );
};

export default Square;

useState:関数コンポーネントでstateを利用するためのフック

const [state変数, stateを変更する関数] = useState(初期値)
  1. ChromeのReact Devtools 拡張機能でstateを確認する。
クリック前
クリック後

ゲームを完成させる

Stateのリフトアップ

stateを親コンポーネント(Board)で保持するようにする。子コンポーネントから親コンポーネントにstateをリフトアップする、という。

  1. Board.tsxに9マス分の状態を保持できるstateを作成する。
import React from "react"; // 追加
import Square, {StateType} from "./Square";
              // ↑ StateType を追加

const renderSquare = (i: number) => {
  return <Square value={i} />;
};

const Board = () => {
  // ↓追加
  const [squares, setSquares] = React.useState<StateType[]>(
    [null, null, null,
    null, null, null,
    null, null, null,]
  );
  //↑追加
  const status = 'Next player: X';

  1. 個別のSquareに現在の値(’○’, ‘×’, またはnull)を伝えるように変更する。
import React from "react";
import Square, {StateType} from "./Square";

const Board = () => {
  const [squares, setSquares] = React.useState<StateType[]>(
    [null, null, null,
    null, null, null,
    null, null, null,]
  );

 const renderSquare = (i: number) => {
   return <Square value={squares[i]} />; // stateを渡す様に変更
 }

 const status = 'Next player: X';

  1. マス目をクリックした際に、関数を呼んでもらうように変更する。
  const renderSquare = (i: number) => {
    return (
      <Square
        value={squares[i]}
        onClick={() => handleClick(i)} // 追加
      />
    );
  };
  1. Square.tsxをpropsを受け取れる用に変更する。
// import React from 'react'; // 削除

type SquareProps = {
  value: StateType; // 変更
  onClick: VoidFunction; // 追加
};
export type StateType = 'O' | 'X' | null;

const Square = (props: SquareProps) => {
  // ↓ 削除
  // const [state, setState] = React.useState<StateType>(null);
  // const handleClick = () => {
  //   console.log('click');
  //   setState('×');
  // };
  // ↑ 削除
  return (
    <button
      className="square"
      onClick={props.onClick} // 変更
    >
      {props.value}
    </button>
  );
};

export default Square;
  1. Board.tsxにマス目をクリックした時に値をセットする関数を記述する。
  const handleClick = (i: number) => {
    const sq = squares.slice();
    sq[i] = 'X';
    setSquares(sq);
  };

チュートリアルによると、.slice()メソッドを使用して、squares配列をコピーするのが良いということだ。

コメント

タイトルとURLをコピーしました