65
40

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

IT芸人Advent Calendar 2019

Day 4

ゆ、useEffectちゃん!初回に動かないで!

Last updated at Posted at 2019-12-04

TL;DR

よいしょ……よいしょ……
useEffect便利ですよね。
stateの変化を監視し、そのstateの変化に伴うべき処理の流れを一元管理できます。

import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom'

function Counter(props) {
  const [count, setCount] = useState(0)
  const [lastUpdatedAt, setLastUpdatedAt] = useState(null)

  useEffect(() => {// 『count』 が更新された際に、それに伴い必ず実行される
    setLastUpdatedAt(new Date().toString())
  }, [count]) 

  return (
    <div>
      <p>カウント {count} 回目</p>

      {/* 変な要件の機能だなぁ…🤔 */}
      <p>🎉最終カウントアップ日時🎉 {lastUpdatedAt || ''} </p>

      <p>
        <button onClick={() => setCount(count + 1)}>カウントアップ</button>
      </p>
    </div>
  )
}

ReactDOM.render(
  <Counter />,
  document.getElementById('root')
)

かなしいところ

(上記例の様に)何も考えずそのまま使うと、対象のstateが変更されているか否かに関わらず、初回レンダー時『にも』必ず動いてしまう。

キャプチャ.PNG

カウントまだ1回もしてないのに「最終カウントアップ日時」出てんのおかしいダルルォン!?(うるさいですね・・・)

かいけつ

useRefを使う。

import React, { useState, useEffect, useRef } from 'react'
import ReactDOM from 'react-dom'

function Counter(props) {
  const [count, setCount] = useState(0)
  const [lastUpdatedAt, setLastUpdatedAt] = useState(null)

  const isFirstRender = useRef(false)

  useEffect(() => { // このeffectは初回レンダー時のみ呼ばれるeffect
    isFirstRender.current = true
  }, [])

  useEffect(() => {// 『count』 が更新された場合『と』初回レンダー時に動くeffect
    if(isFirstRender.current) { // 初回レンダー判定
      isFirstRender.current = false // もう初回レンダーじゃないよ代入
    } else {
      setLastUpdatedAt(new Date().toString())      
    }
  }, [count]) 

  return (
    <div>
      <p>カウント {count} 回目</p>

      <p>🎉最終カウントアップ日時🎉 {lastUpdatedAt || ''} </p>

      <p>
        <button onClick={() => setCount(count + 1)}>カウントアップ</button>
      </p>
    </div>
  )
}

ReactDOM.render(
  <Counter />,
  document.getElementById('root')
)

かつてのクラスコンポーネントで言う所の「componentDidUpdate」と似た働きが期待出来ます。

けつろん

結果オーライ! 終わりやっぱりReactはたのしい。以上。

65
40
1

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
65
40

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?