Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Reactを学ぶX 〜ReactHooks〜

■ はじめに

タイトルについて記事にしました。
この記事で得る内容は以下の通りです。

・ Reactの基礎知識が増える
・ ReactHooksについて

■ フック(hook)とは

・ クラスの機能(stateやライフサイクル)をFunctional Componentでも使える

・ React 16.8から導入(2020年2月に正式リリース)

・ 100%後方互換 → ReactHooksと従来記述していた構文は干渉しない

→ ただ、あくまでReactHooksは選択肢の一つであり、Class Componentを置き換えるものではない

■ なぜフックを使うのか?

A. シンプルさを保つため

・ Class Componentは難しい

thisがReactは他言語と比べ異なる挙動をするので、なるべく使いたくない
 ですが、Class Componentを使うと、どうしてもthisを使わないといけない

→ stateを扱うロジックが複雑

→ 複数のライフサイクルメソッドに(同じような)副作用のあるメソッドがまたがる

sample.jsx
componentDidMount() {
    this.counter.addEventListener(
        'click', this.countUp
    )
}
componentWillUnmount() {
    this.counter.removeEventListener(
        'click', this.countUp
    )
}

// 前回のいいねボタンは、componentDidMountでイベントリスナーを設定して、componentWillUnmountでイベントリスナーを解除していた
// 時間の流れでコードを分けるのではなくて、一つの機能を一つの場所にまとめて書いておく方がわかりやすい

これらの課題を解決する手段として、次第にフックが使われ始めました

■ usestate()メソッド

・ Functional Copmponentでもstateを使う方法

・ ステートフックと呼ばれている

・ Class Componentでいうthis.statesetStateの代替

・ 複数のstateを扱う時は、usestate()をstate毎に宣言します

■ usestate()メソッドの使い方

sample.jsx
// ① useState関数をインポート
import React, {useState} from 'react';

// ② 宣言をする
const [isPublished, togglePublished] = useState(false);
//    state変数名    state変更関数名         state初期値

// ③ JSX内で使う
<input /** 中略 */ onClick={() => togglePublished(!isPublished)}/>
// 例:inputタグでクリックされたら、stateを変更する関数を呼び出して、isPublishの値を反転させる

■ 例

前使っていたプロジェクトのBlog.jsxとArticle.jsxを使って
Blog.jsxで記述していたBlogクラスをFunctional Componentに置き換えます

✳︎今回、不要な所をコメントアウトしています

Blog.jsx
import React from "react";
import Article from "./Article";
import * as FooBar from "./components/FooBar";
import Hoge from "./components/Hoge";

const Blog = () => {
  // componentDidMount() {
  //   // ボタンがクリックされたらいいねをカウントアップする
  //   document.getElementById("counter").addEventListener("click", this.countUp);
  // }

  // componentDidUpdate() {
  //   if (this.state.count >= 10) {
  //     this.setState({ count: 0 });
  //   }
  // }

  // componentWillUnmount() {
  //   document.getElementById("counter").removeEventListener("click", this.countUp);
  // }

  // countUp = () => {
  //   this.setState({
  //     count: this.state.count + 1,
  //   });
  // };

  return (
    <>
      <Article
        title={"Reactの使い方"}
        // count={this.state.count}
      />
      <FooBar.Foo />
      <FooBar.Bar />
      <Hoge />
    </>
  );
};

export default Blog;

Functional ComponentだったArticle.jsxは、stateを持つことができませんでしたが
usestate()メソッドを使うことで、stateを持たせることができます

Article.jsx
import React, { useState } from "react"; // useStateを使えるようにする
// import LikeButton from "./LikeButton";

const Article = (props) => {
  const [isPublished, togglePublished] = useState(false); // useStateメソッド(state変数名・stateを変更する変数名・useState初期値)

  return (
    <div>
      <h2>{props.title}</h2>
      <label htmlFor="check">公開状態:</label>
      <input type="checkbox" checked={isPublished} id="check" onClick={() => togglePublished(!isPublished)} />
      {/* <LikeButton count={props.count} /> */}
    </div>
  );
};

export default Article;

チェックボックスをクリックしたら、useStateで作ったtogglePublishedの引数(isPublished)を渡して!でFalseを反転させます

functionalでも使える.gif

Functional Componentでもstateを扱う事ができて、同時にstateの変更も行えるようになります

s79ns
100記事投稿を目標に、質にも拘った良記事を書き続けます🔥
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away