コピペコードで快適生活

明日使えるソースを自分のために

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];
}

参考