0
1

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

FizzBuzzボタンを作りながらReact Hooksを学ぶ 第2回

Posted at

FizzBuzz ボタンを作りながら React Hooks を学んでいきます。
目次はこちら

FizzBuzz ボタンを整理する

前回、クラスコンポーネントと state を使って FizzBuzz ボタンを作りました。
今回は前回作ったものを整理して、ファイルを分割します。

具体的には

  1. FizzBuzz を状態管理部分と表示部分に分離してそれぞれ別ファイルに
  2. 関数 fizzBuzz も別ファイルに

していきます。
まだ Hooks は出てきません。

FizzBuzz を別ファイルに切り出すので、App.tsx は以下のようにシンプルになります。

App.tsx
import React from 'react';
import FizzBuzz from './FizzBuzz';

const App: React.FC = () => {
  return <FizzBuzz initialCount={0} />;
};

export default App;

FizzBuzz.tsx はこんな感じ。
表示部分を FizzBuzzView として、別ファイルに切り出しました。
また、メッセージの作成部分 fizzBuzz も別ファイルに切り出しました。

FizzBuzz.tsx
import React from 'react';
import FizzBuzzView from './FizzBuzzView';
import { fizzBuzz } from './common';

type Props = {
  // props で count の初期値を受け取る
  initialCount: number;
};

type State = {
  // 状態として count を持つ
  count: number;
};

// クラスコンポーネントで FizzBuzz ボタンを作る
class FizzBuzz extends React.PureComponent<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = {
      count: props.initialCount,
    };
  }

  // マウントされたときの処理
  componentDidMount() {
    console.log('mount');
  }

  // アンマウントされたときの処理
  componentWillUnmount() {
    console.log('unmount');
  }

  // +1 ボタンを押すと count をインクリメントする
  plus1 = () => this.setState(({ count }) => ({ count: count + 1 }));

  // clear ボタンを押すと count をリセットする
  clear = () => {
    const { initialCount } = this.props;
    this.setState({ count: initialCount });
  };

  render() {
    console.log('render');
    const { count } = this.state;
    const { plus1, clear } = this;
    const message = fizzBuzz(count);

    return (
      <FizzBuzzView
        count={count}
        message={message}
        plus1={plus1}
        clear={clear}
      />
    );
  }
}

export default FizzBuzz;

FizzBuzz の表示部分です。
値(count)とメッセージ(message)、ボタンを押したときの処理(plus1, clear)を props で受け取ります。
state を使わないので、関数コンポーネントで実装します。

FizzBuzzView.tsx
import React from 'react';

type Props = {
  count: number;
  message: string;
  plus1: () => void;
  clear: () => void;
};

const FizzBuzzView: React.FC<Props> = React.memo(
  ({ count, message, plus1, clear }: Props) => (
    <div>
      <div>{`${count} ${message}`}</div>
      <div>
        <button type="button" onClick={plus1}>
          +1
        </button>
        <button type="button" onClick={clear}>
          clear
        </button>
      </div>
    </div>
  )
);

export default FizzBuzzView;

fizzBuzz は React と無関係な純粋な関数ですので、ファイルの拡張子は .tsx ではなく .ts にしておきます。

common.ts
// count の値に応じて fizzBuzz メッセージを返す
export const fizzBuzz = (count: number) => {
  if (count === 0) {
    return '';
  }
  if (count % 3 === 0 && count % 5 === 0) {
    return 'FizzBuzz';
  }
  if (count % 3 === 0) {
    return 'Fizz';
  }
  if (count % 5 === 0) {
    return 'Buzz';
  }
  return '';
};

今回作成したソースコードはこちら
次回は FizzBuzz ボタンの動作をわかりやすくするために App を少し改造します。

0
1
0

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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?