Reactを学習することになったのでチュートリアルをやってみようと思う。しかし、チュートリアルはTypescriptではないので、調べながら変更していこうと思う。
前回からのつづき
概要
データをProps経由で渡す
Board.tsx
のrenderSquare
メソッド内で、propsとしてvalue
という名前の値をSquareに渡す。
const renderSquare = (i: number) => {
return <Square value={i} />;
};
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;
インタラクティブなコンポーネントを作る
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(初期値)
- ChromeのReact Devtools 拡張機能でstateを確認する。
ゲームを完成させる
Stateのリフトアップ
stateを親コンポーネント(Board)で保持するようにする。子コンポーネントから親コンポーネントにstateをリフトアップする、という。
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';
- 個別の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';
- マス目をクリックした際に、関数を呼んでもらうように変更する。
const renderSquare = (i: number) => {
return (
<Square
value={squares[i]}
onClick={() => handleClick(i)} // 追加
/>
);
};
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;
Board.tsx
にマス目をクリックした時に値をセットする関数を記述する。
const handleClick = (i: number) => {
const sq = squares.slice();
sq[i] = 'X';
setSquares(sq);
};
チュートリアルによると、.slice()
メソッドを使用して、squares配列をコピーするのが良いということだ。
コメント