ReactHooksを使ってみる
最近のReactでは関数コンポーネント&ReactHooksを使うのが主流らしい。
キャッチアップしたところ、state管理がコンポーネントからキレイに分離できてよさそうだった。
index.tsx
import * as React from "react"; import * as ReactDOM from "react-dom"; import Omikuji from "./Omikuji"; let element: JSX.Element = <Omikuji name="kinosuke01"/>; let dom: HTMLElement = document.getElementById('root'); ReactDOM.render(element, dom);
Omikuji.tsx
import React from 'react'; import useOmikuji from './useOmikuji'; interface Props { name: string, }; interface State { }; export default function Omikuji(props: Props) { // state管理を行う処理を、関数コンポーネントに組み込む。 let [result, updateResult] = useOmikuji(); let message: string = '今日の運勢を占います!'; let buttonText: string = '占う!'; if (result) { message = `${props.name}さんの今日の運勢は「${result}」です!!`; buttonText = 'もう一度占う!'; } return ( <div> <p>{message}</p> <button onClick={() => updateResult()}>{buttonText}</button> </div> ) };
useOmikuji.ts
import { useState, useEffect } from 'react'; // // 関数コンポーネントにstate管理を組み込む関数。 // state管理をコンポーネントから分離できる。 // 複数のコンポーネントで使い回すことができる。 // setResultやuseEffectを使うことで実現。 // export default function useOmikuji(): [string, Function] { // result -> state.result // setResult -> setState({result: xxx}); // に対応するイメージ // useStateの引数は、対象stateの初期値 const [result, setResult] = useState(null); function predict(): string { let i: number = Math.floor(Math.random() * 10 % 5); let list: Array<string> = ['大吉', '吉', '中吉', '小吉', '凶']; return list[i]; } function updateResult(): void { setResult('占い中...'); setTimeout(() => { let predictResult: string = predict(); setResult(predictResult); }, 1000); } // useEffectには、 // componentDidMount, componentDidUpdate の // タイミングで呼びたい関数を渡す useEffect(() => { console.log(`「${result}」を取得しました。`); // 戻り値には、componentWillUnmountの // タイミングで呼びたい関数を渡す return (): void => { console.log('さよなら'); return; }; }); return [result, updateResult]; }