はじめに
React のHooksのUseEffectのメモです。
ご指摘、感想、お待ちしています。。。
目次
- まずはクラスで普通に書いてみる
- 関数コンポーネントで書き換え
- コンポーネントが削除される時は?
1. まずはクラスで普通に書いてみる
まずはクラスでチュートリアルにあるようなカウンターを書いてみます。
コンポーネントがマウントされた際に
componentDidMount()
でカウントをコンソールログに出力しています。
componentDidUpdate()
で更新が行われる度に同じくログを出力しています。
これを関数コンポーネントで書き換えてみましょう。
import React, { Component } from 'react'
class ClassCounter extends Component {
constructor(props) {
super(props)
this.state = {
count: 0
}
}
componentDidMount() {
console.log(`Class Counter Mount !! ${this.state.count}`)
}
componentDidUpdate() {
console.log(`Class Counter Update !! ${this.state.count}`)
}
render() {
const { count } = this.state
return (
<div>
<button onClick={() => this.setState({ count: count + 1 })}>
Click {count} times
</button>
</div>
)
}
}
export default ClassCounter
2. 関数コンポーネントで書き換え
ポイントはuseEffect
の第2引数です。
空のリストの場合は、初回マウント時のみ
リストの中にstateを指定すると、そのstateが更新された時のみ
それぞれログが出力されるようになります。
また、リストには複数のstateを指定できます。
その場合は、どちらかが更新されるとログが出力されます。
import React, { useState, useEffect } from 'react'
export default function FunctionCounter() {
const [count, setCount] = useState(0)
const [text, setText] = useState('')
const [isShow, setShow] = useState(true)
// レンダリングされた時にのみ実行
useEffect(() => {
console.log(`Function Component Mount`)
}, [])
// countが更新された時に実行
useEffect(() => {
console.log(`count state is updated ${count}`)
}, [count])
// textが更新された時に実行
useEffect(() => {
console.log(`text state is updated ${text}`)
}, [text])
// count または textが更新された時に実行
useEffect(() => {
console.log(`state text and count are updated count=${count} text=${text}`)
}, [text, count])
return (
<div>
<input type='text' value={text} onChange={e => setText(e.target.value)}></input>
<button onClick={() => setCount(count + 1)}>
Click {count} times
</button>
</div>
)
}
3. コンポーネントが削除される時は?
ボタン操作でClassChildComponent
を表示を切り替えてみます。
import React, { Component } from 'react'
import ClassChildComponent from './ClassChildComponent'
class ClassComponent extends Component {
constructor(props) {
super(props)
this.state = {
isShow: false
}
}
render() {
const { isShow } = this.state
return (
<div>
<button onClick={() => this.state.isShow ?
this.setState({ isShow: false }) : this.setState({ isShow: true })}>
isShow is {isShow}
</button>
{isShow && <ClassChildComponent />}
</div>
)
}
}
export default ClassComponent
ClassChildComponentの方でコンポーネントが削除される際の
componentWillUnmount()
を定義しています。
これをuseEffectで書き換えます。
import React, { Component } from 'react'
export default class ClassChildComponent extends Component {
componentWillUnmount(){
console.log('Child Class Component will Unmount !!')
}
render() {
return (
<div>
<h3>Child Component</h3>
</div>
)
}
}
まずは、同じように表示を切り替えるボタンのみのコンポーネントを準備します。
import React, { useState} from 'react'
import FunctionChildComponent from './FunctionChildComponent'
export default function FunctionComponent() {
const [isShow, setShow] = useState(false)
return (
<div>
<button onClick={() => isShow? setShow(false) : setShow(true)}>
isShow is {isShow}
</button>
{isShow && <FunctionChildComponent />}
</div>
)
}
呼び出すコンポーネントはこんな感じ
useEffectの中でreturn()を定義してあげると、componentWillUnmountと同じ動きになります。
import React, {useEffect} from 'react'
export default function FunctionChildComponent() {
useEffect(() => {
return () => {
console.log('Child Function Component will Unmount !!')
};
}, [])
return (
<div>
<h3>Child Component</h3>
</div>
)
}