#はじめに
今回はReactの使い方についてまとめていきます。
環境構築については、以下の記事を参考にしてください。
#コンポーネントについて
Reactはコンポーネント(部品)という単位で実装していきます。
Webサイトやアプリは、ボタンやタブなどのコンポーネントの集まりと考えることができます。
例えば、このQiitaだと以下のようなコンポーネントが存在すると考えることができます(適当です)。
- ボタンコンポーネント
- ナビゲーションコンポーネント
つまり、コンポーネントとは見た目
と機能
を組み合わせたものだと考えることができます。
このように、コンポーネントという単位でプログラムを管理すると、再利用することができたり、変更してもバグが起きにくいという利点がありますよね。
それでは実際にコンポーネントの種類を見ていきましょう。
今回は、npx create-react-app
というコマンドを使ってReactアプリを作成し、そのアプリに各々のコードを記述して動きを見ていきます。
##Functional コンポーネントについて
Functionalコンポーネントについて見ていきましょう。
create-react-app
を行うと、以下のようなファイル構成になります。
この中のApp.jsx
に以下のようにコードを記述してください。
import React from 'react'
const App = (props) => {
return (
<div>
<h1>Hello World</h1>
</div>
)
}
export default App
このように、Javascriptの関数のようにReactのコンポーネントを作成して、外部にエクスポートしています。
Functionalコンポーネントは、アロー関数またはfunction()で定義した関数のどちらを用いて記述します。
関数内のreturn
の後に、JSX
と呼ばれるHTMLのようなものを記述します。
ここでは使用していませんが、引数で渡しているpropsに、親コンポーネントから呼び出す際に変数を格納されることができます。
ちなみに、このエクスポートされたApp関数はindex.js
で呼び出されます。
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
serviceWorker.unregister();
上記のように、index.js
はApp.jsx
ファイルからエクスポートされたAppコンポーネント
を読み込み、それをReactDOM
に渡すことでrender(描画)しています。
yarn start
を行い、実行結果を見てみましょう。
このように、Reactアプリを起動させるとindex.js
ファイルが実行され、ReactDOMがrender(描画)されていることが分かります。
##クラスコンポーネントについて
クラスコンポーネントは以下のように作成します。
import React from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
open: 'pocomaru'
}
}
render() {
return (
<div>
<h1>Hello World</h1>
<h1>{this.state.id}</h1>
</div>
);
}
}
export default App
Javascriptのクラスを作成する際に、React.Component
というクラスを継承しています。
その後に、constructor
により、初期値のstate
をセットします。コンストラクタとは、オブジェクト作成時に実行されるメソッドのことでしたね。
引数に渡しているprops
は、エクスポートしたAppコンポーネントを呼び出すときに渡した値が代入される箱のようなものです。
super(props)
とすることで、親クラスを継承しています。
その後に、this.state
にオブジェクトを代入します。このthisは、このクラス自身のことです。今、Appクラスのopen stateがtrueに設定されています。
このstateに設定されている値を用いる場合、this.state.id
とすればアクセスできます。
return以降はJSXと呼ばれる部分になります。この部分では、通常の書き方ではJavascriptコードを使用することができません。
そのため、this.state.id
の値にアクセスするためには、中括弧{}で囲う必要があります。
この状態でReactアプリを起動すると以下のようになります。
#Functionalコンポーネントとクラスコンポーネントの違い
最初にFunctionalコンポーネントの特徴から解説します。以下の特徴を持ちます。
- stateを持たない
- propsを引数に持つ
順番に解説します。
###stateとは
stateとは、その名の通り状態のことです。
例えば、扉コンポーネントというものを考えたとき、扉が開いているのか
や閉じているのか
というコンポーネントの状態を示すのがstateです。
ボタンコンポーネントでは、押されたことがある
のか押されたことがないのか
というのもstateで管理できますし、何回押されたのか
などもstateで管理できます。
Functionalコンポーネントはクラスコンポーネントと違って、このstateを持つことができません。
React-hooksなどを用いればstateを持たせることは可能ですが、ここでは割愛させて頂きます。
###propsを引数に持つとは
Functionalコンポーネントは、propsを引数に持つことができます。ちなみにクラスコンポーネントもコンストラクタにpropsを渡すので、Functionalコンポーネントだけの機能ではありませんが。
propsとは、親コンポーネントから渡す値を格納する箱
のようなものです。
具体例で確認してみましょう。
App.jsx
という親コンポーネントからName.jsx
というコンポーネントを呼び出し、propsとしてnameを渡すことを考えてみましょう。以下のようになります。
import React from 'react';
import Name from './Name';
const App = (props) => {
return(
<div>
<Name name='pocomaru'/>
</div>
)
}
export default App
このファイルでは、Name.jsx
の中のName
関数コンポーネントをインポートしています。
そのインポートした関数のname属性にpocomaru
という値を渡しています。
この渡した値には、props.name
とすることでアクセスできます。Name.jsxの中身を確認してみましょう。
import React from 'react';
const Name = (props) => {
return (
<h1>{props.name}</h1>
)
}
export default Name
結果は以下のようになります。
それでは次にクラスコンポーネントについて見ていきましょう。
以下の特徴があります。
- ライフサイクルをもつ
- stateを持つ
それぞれについて解説していきます。
###ライフサイクルをもつ
クラスコンポーネントはライフサイクルを持ちます。
ライフサイクルとは、コンポーネントが生まれて、成長し、死ぬまでの循環のことです。
こんなことを言われても意味がわからないと思うので、具体的に説明します。
ボタンコンポーネントのライフサイクルについて考えてみましょう。
ある日、ボタンコンポーネントが誕生しました。マウントされるとも言いますね。
Reactにおいては、このボタンコンポーネントが誕生した瞬間
にconstructor
が走ります。stateに値を代入する処理などですね。
そのようにしてconstructorが走った後は、renderが走ります。これによりReactが描画され、画面で見ることができます。
この後に、componentDidMount
という関数が走ります。このcomponentDidMount`に何か操作をかいておけば、コンポーネントがマウントされた後に一度だけ使うことができます。
ここまでが生まれたときの話です。次は、コンポーネントが成長していくときの話をしましょう。
コンポーネントが誕生した後は、度重なるrenderがユーザーの操作により発生します。
具体的にはrenderは、ユーザーの操作などによりstateが変更されるたびに呼び出されます。
これがライフサイクルの成長の過程であり、renderされる毎にcomponentDitUpdate
という関数が実行されます。
最後に、コンポーネントが死ぬときの話をしましょう。
コンポーネントが死ぬ直前、つまりはアンマウントされる直前にcomponentWillUnmount
という関数が実行されます。
このように、ライフサイクルに合わせてcomponentDidMount
などのメソッドを実行することができ、これらはクラスコンポーネントでしか使用することができません。React-hooksを使えば、Functionalコンポーネントでも用いることができますが。
それでは次に、ライフサイクルについて解説していきます。
#ライフサイクルの種類
ライフサイクルには、以下の三種類があります。
-
Mounting
-
Updating
-
UnMounting
各々について解説していきましょう
###Mountingとは
Mountingとは、コンポーネントが生まれるときの期間のことです。
このMountingのときに使われるライフサイクルメソッドは、マウントが行われる直前に実行されるcomponentWillMount
とマウントが実装された直後に実行されるcomponentDidMount
です。
ちなみにマウントが行われる直前に実行されるcomponentWillMount
は非推奨なので使わないほうがよいです。
##Updatingとは
Updatingとは、コンポーネントが変更される期間のことです。
クラスコンポーネントはライフサイクルとstateを持つことができます。
つまり、コンポーネントが変更されるとはこのstateが変更されることを指します。
例えば、ボタンコンポーネントを実装するとします。このボタンコンポーネントの元々の色は赤色で、ボタンをクリックすると青色になるという機能をもたせたいとします。
どのように実装するかというと、このボタンコンポーネントにstateを持たせて管理することが考えられます(例えばcolorコンポーネントを持たせてクリックにより変更させるなど)。
Reactにおける重要な点の一つは、このstateが変更されたときにrenderが走るということです。つまり、stateが変更されるたびに画面の一部分を再描画していきます。
なぜこのような事になっているのかというと、stateの変更を画面に反映させるためです。例えば先ほどの例でボタンコンポーネントをクリックして、colorというstateを赤色から青色に変更させたとします。しかし、例えstateが変更されたとしても、render(描画)されなければ画面に反映されません。そのため、Reactではstateが変更されるたびにrenderが呼ばれるようになっています。
このstateが変更されてrenderされる
という時がUpdatingの期間であり、その前後に対応したライフサイクルメソッドが走ります。Updatingにおけるライフサイクルメソッドは、以下の4つが考えられます。
-
componentWillReactiveProps マウントされたコンポーネントが新しいpropsを受け取る前
-
shouldComponentUpdate 新しいpropsやstateを受け取った時
-
componentWillUpdate 新しいpropsやstateを受け取った後、レンダリングする直前
-
componentDidUpdate 更新が行われた直後
##Unmountingとは
コンポーネントが破棄される期間のことをUnMountingの期間といいます。
componentWillUnmount
というライフサイクルメソッドが、コンポーネントが破棄される直前に呼び出されます。
それでは実際に、これらのライフサイクルメソッドを実装してみましょう。
#componentDidmountの実装
componentDidmountは、次の用途で用いられます。
- Ajaxを使ったデータフェッチを行う(初回)
- DOMに対する処理を行う(初回)
- タイマーをリセットする
- イベントリスナのセット
今回は、イベントリスナのセットを行っていきましょう。
LikeButtonコンポーネントを作成して、クリックするといいね数が増えていくという機能を実装します。
以下のように、App.jsxとLikeButton.jsxを実装しましょう。
import React from 'react';
import LikeButton from './LikeButton';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
}
}
componentDidMount() {
document.getElementById("counter").addEventListener('click', () => this.setState({count: this.state.count + 1}))
}
render() {
return (
<div>
<LikeButton count={this.state.count} />
</div >
)
}
}
export default App
import React from 'react';
const LikeButton = (props) => {
return (
<div>
<button id="counter">いいね数: {props.count}</button>
</div>
)
}
export default LikeButton
結果は以下のようになります。
それではコードの解説をしていきます。
constructor(props) {
super(props);
this.state = {
count: 0
}
この部分で、Appコンポーネントのstateとしてcountを持たせています。
このstateをLikeButtonコンポーネントに渡して、その中のButtonをクリックするたびに、このstateが更新されていけば良いわけですね。
今回は、componentDidMount
を用いてイベントリスナーを設定しています。イベントリスナーとは、イベント(文字入力やボタンクリックなど)が行われたことを検知して発動する関数のことです。これにより、コンポーネントが誕生したときにイベントリスナーをコンポーネントに設定することができます。
今回は、クリックというイベントが発生したときに、() => this.setState({count: this.state.count + 1}
という関数が実行されるようになりました。
クラスコンポーネントのstateを変更するときは、このようにsetStateメソッド
を用いて、そのメソッド内で関数またはオブジェクトを指定することにより、stateを変更することができます。クラスコンポーネント内でstateにアクセスするときにはthis.state.***
としてアクセスします。ちなみに、このsetStateメソッド内で関数を渡すかオブジェクトを渡すかの違いによって、挙動が異なります。詳しくは以下の記事を参考にしてください。
React の setState() の引数が関数の場合とオブジェクトの場合の違いについて整理する
また、以下のコードでLikeButtonコンポーネントを呼び出し、propsとしてthis.state.count
を渡しています。
<LikeButton count={this.state.count} />
このようにして渡したstateを、LikeButtonコンポーネントではprops.count
という形で利用しています。
<button id="counter">いいね数: {props.count}</button>
このbuttonタグのidにcounter
を指定しています。このタグは、親コンポーネントであるApp.jsxからも指定して呼び出すことができます。
ここまでで、componentDidMountを用いてコンポーネントが誕生した直後にイベントリスナーを設定することができました。
###補足 別の方法で同じ機能を実装
また、今回の機能はApp.jsxからpropsとしてcountを更新する関数を渡し、それを子供のコンポーネントのボタンタグのonClick
に指定することでも実装できます。
import React from 'react';
import LikeButton from './LikeButton';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
}
}
UpdateCounter = () => {
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<LikeButton count={this.state.count} UpdateCounter={this.UpdateCounter} />
</div >
)
}
}
export default App
import React from 'react';
const LikeButton = (props) => {
return (
<div>
<button onClick={props.UpdateCounter}>いいね数: {props.count}</button>
</div>
)
}
export default LikeButton
#componentDidUpdateの実装
それでは次にstateが更新されてrenderが走った後に呼び出されるcomponentDidUpdateを実装していきましょう。
このライフサイクルメソッドは、stateがある閾値を超えたときに別の動作をするようにしたい
ときなどに実装すると便利ですね。
今回は、いいね数が5という閾値を超えた際に、いいね数を0にするという機能を実装していきます。
componentDidUpdateはstateが更新され、それによりrenderが走った後に呼び出されます
つまり、その更新されたstate
に対して更新されるたびにif文やswich文で比較を行い、指定した値になったときに指定した関数を実行する、といった処理を実装していきます
今回はthis.state.count
の値をcomponentDidUpdateの中で5と比較し、5以上になったときにthis.state.count
の値をsetState
メソッドを用いて0にするという機能を実装していきます。
以下のコードです。
import React from 'react';
import LikeButton from './LikeButton';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
}
}
componentDidMount() {
document.getElementById("counter").addEventListener('click', () => this.setState({count: this.state.count + 1}))
}
componentDidUpdate(){
if (this.state.count >= 5) {
this.setState({
count: 0
})
}
}
render() {
return (
<div>
<LikeButton count={this.state.count} />
</div >
)
}
}
export default App
import React from 'react';
const LikeButton = (props) => {
return (
<div>
<button id="counter">いいね数: {props.count}</button>
</div>
)
}
export default LikeButton
以前の状態から追記したコードは以下だけです。
componentDidUpdate(){
if (this.state.count >= 5) {
this.setState({
count: 0
})
}
}
このコードにより、stateの値が更新されるたびにthis.state.count
が5以上かどうかを確認することになります。
実行結果は以下のようになります。
#componentWillUnmountの実装
このメソッドは主に次の機能を実装したいときに使います。
- タイマーを解除する
- イベントリスナーを解除する
- 非同期処理を中止する
今回は、イベントリスナーを解除してメモリを開放する機能を実装していきましょう。
以下のコードです。
import React from 'react';
import LikeButton from './LikeButton';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
}
}
componentDidMount() {
document.getElementById("counter").addEventListener('click', () => this.setState({count: this.state.count + 1}))
}
componentDidUpdate(){
if (this.state.count >= 5) {
this.setState({
count: 0
})
}
}
componentWillUnmount() {
document.getElementById('counter').removeEventListener('click', () => this.setState({count: this.state.count + 1}))
}
render() {
return (
<div>
<LikeButton count={this.state.count} />
</div >
)
}
}
export default App
import React from 'react';
const LikeButton = (props) => {
return (
<div>
<button id="counter">いいね数: {props.count}</button>
</div>
)
}
export default LikeButton
これでコンポーネントがアンマウントされたときにイベントリスナーを削除して、メモリを開放することができるようになりました。
追記したのは以下の部分です。
componentWillUnmount() {
document.getElementById('counter').removeEventListener('click', () => this.setState({count: this.state.count + 1}))
}
このコードにより、イベントリスナーを削除することができています。
それでは次に、ReactのHooksについてまとめていきます。
#Hookとは
Hookとは、端的に言えばクラスコンポーネントの機能をFunctionalコンポーネントでも使えるようにするためのものです。
具体的には、今まではクラスコンポーネントでしか持つことができなかったstateやライフサイクルをFunctionalコンポーネントで利用できるようになります。
今までReactの様々な機能にアクセスできるクラスコンポーネントと違い、一切のアクセスが許可されていなかったFunctionalコンポーネントをReactの機能へ接続(Hooks into)するという意味で、Hooksと呼ぶらしいです。
#なぜHookを使うのか
察しの良い皆さんならこう思ったはずです。
「stateやライフサイクルメソッドが使いたいならクラスメソッド使えば良くね?」
確かに一理あります。
しかし、クラスコンポーネントには以下で示すような問題がありました。
- 処理が散らばりやすい
- thisを使いたくない
- 複数のライフサイクルメソッドに処理がまたがるのが嫌だ
- そもそもクラスコンポーネントの構文が複雑
- stateの扱い方が複雑
この中のいくつかの問題点を、さらに深く解説していきます。
##処理が散らばりやすい
Reactを書いたことがある皆さんなら共感頂けると思いますが、クラスコンポーネントはメソッドをいくつも実装できるが故に処理が散り散りになりやすいんですよね。
子供のコンポーネントで行われる処理を、親のクラスコンポーネントのライフサイクルに定義して使いたくなりますよね。
具体例で話すなら、例えば人間コンポーネント
を定義して、それに子供としてハサミコンポーネント
を渡したとします。
このハサミコンポーネントの前に紙が存在するとき
に、ハサミコンポーネントの切断
という機能を実装したいとします。
人間コンポーネントをクラスコンポーネント、ハサミコンポーネントをFunctionalコンポーネントだとすると、紙
はstateを持つ人間コンポーネントで管理することになりますし、紙の状態に応じた処理(ここでは切断する)もライフサイクルを持つ人間コンポーネントの中で書くことになりそうです。
子供のコンポーネントがハサミコンポーネントのみならまだしも、他の様々なコンポーネントのstateやライフサイクルも人間コンポーネントで管理することになると、非常に煩雑になりそうですよね。
そもそも、切断する
という処理はハサミコンポーネントの中の処理であるので、当然の思考としてハサミコンポーネントの中で管理するのが良さそうです。
また、紙
というstateも、紙の状態に応じたライフサイクルを用いた処理も、人間コンポーネントではなくハサミコンポーネントで管理するべきですよね。
ここでハサミコンポーネントをクラスコンポーネントにしてしまっても良いのですが、それだと根源的な解決になりません。
そもそも、ひとつの機能はひとつの場所に
という原則を守って書くことを強制してしまった方が良さそうです。
そこで導入されたのがHookであり、Functionalコンポーネント自体にstateやライフサイクルを管理させるとうものです。
##thisを使いたくない
Javascriptにおけるthisは、他の言語におけるthisとは違う挙動をします。
詳しくは以下の記事を御覧ください。
JavaScript の this を理解する多分一番分かりやすい説明
つまり、簡単に書くとthisの使い方めっちゃむずい
ということです。
こんなものはトラブルの元です。
できるだけ使わないようにしようという動きも多く、そのためクラスコンポーネントはできるだけ使いたくないと思う人も多いようです。
複数のライフサイクルメソッドに処理がまたがるのが嫌だ
クラスコンポーネントのライフサイクルメソッドは、時間の流れで処理を分割します。
そうすると、同じような機能が複数のライフサイクルメソッドに跨ってしまうことがありますよね。
そのように記述するよりも、同じ機能は同じ場所
と言う方が分かりやすいと考える人も多いようです。ちなみに私もそう思います。
#React-Hooksの実装
それでは実際にHooksを実装してみましょう。
##Hooksでstateの管理
まず、Hooksでstateの管理をしていきます。
HooksはFunctionalコンポーネントにおけるstateの管理やライフサイクルメソッドの実装に用いるんでしたね。
Hooksでstateを用いるときは、useState
というメソッドを使います。
実際にコードで確認してみましょう。
今回は、ScissorsコンポーネントというFunctionalコンポーネントを作成して、それを親コンポーネントであるAppコンポーネントから呼び出します。
そのScissorsコンポーネントにcutting
とうstateを持たせて、ボタンを押すことで変化させるという機能を実装します。
以下がコードです。
import React from 'react';
import Scissors from './Scissors'
const App = () => {
return(
<div>
<Scissors />
</div>
)
}
export default App
これはシンプルにScissorsコンポーネントを呼び出しているだけですね。以下がそのScissorsコンポーネントです。
import React, { useState } from 'react';
const Scissors = () => {
const [cutting, changeCutting] = useState("NoCutting");
return(
<div>
<h1>{cutting}</h1>
<button onClick={() => changeCutting("YesCutting!")}>change </button>
</div>
)
}
export default Scissors
それではHooksの部分を解説していきます。
以下の部分でuseStateをインポートしています。
import React, { useState } from 'react';
これでインポートすることができました。
次の部分が、useStateを使う上で肝となる部分です。以下のコードです。
const [cutting, changeCutting] = useState("NoCutting");
それでは解説します。
cutting
がstateであり、changeCutting
がstateを変更させる関数です。ちなみに、このchangeCutting
に引数を渡して実行すれば、cutting
の値がその引数に渡した値に変化します。
つまり、このuseState関数は、state
とstateを変更させる関数
を同時に定義していると考えることができますね。
クラスコンポーネントでは、constructorの部分でthis.state = {}
という感じにstateを定義し、setState
を用いてそのstateを変更していたと思います。
それでは、useState
の引数の部分は何を意味するのでしょうか。
正解は、stateの初期値
になります。
つまり、上のコードはcutting
というstateを作成し、その初期値にNoCutting
を渡し、それと同時にそのstateを変更させる関数であるchangeCutting
を作成したことになります。またこのchangeCutting
は、実行したときにcutting
の値を引数に指定した値に変更させる関数になります。
以下のコードで、ボタンをクリックしたときにこのchangeCutting
を実行しています。
<button onClick={() => changeCutting("YesCutting!")}>change </button>
buttonタグのonClickにアロー関数としてchangeCutting
を実行したものを渡しています。
onClickはボタンをクリックしたときに引数として渡された関数を実行するという機能なので、このように関数そのものを渡します。
実際にこのReactアプリの挙動を見てみましょう。
ここまでで、Hooksによるstate管理は終わりです。
##Hooksによるライフサイクルの管理
Hooksによるライフサイクルメソッドの代替として、useEffect
メソッドがあります。
以下の三つのメソッドを代替することができます。
- coponentDidMount()
- componentDidUpdate()
- componentWillUnmount()
軽く解説します。
###componentDidMountについて
componentDidMountはマウントが行われた直後に実行されるメソッドです。Ajaxを使ったデータフェッチ(初回)やイベントリスナのセットなどを行います。
###componentDidUpdateについて
componentDidUpdateはstateの更新が行われた直後に行われるメソッドです。具体的には、stateが更新され、その後にrenderが走った後に呼び出されます。
stateがある閾値を超えたときに別の動作をするようにしたい
ときなどに使うと便利ですね。
###componentWillUnmountについて
componentWillUnmountは、コンポーネントが破棄される直前に呼び出されます。
具体的には、イベントリスナーを解除してメモリを開放するときなどに利用されます。
それでは、実際にuseEffect
メソッドを用いてこれらのライフサイクルメソッドを実装してみましょう。
#useEffectメソッドの実装
まず、最初にuseEffectメソッドの使い方解説を行います。
以下の記事を参考にしました。
##第一引数のみ
第二引数を空っぽにすると、第一引数に指定したコールバック関数がrender毎に実行されます。
componentDidUpdate
と同じタイミングで呼ばれることになりますね。
useEffect(() => {
console.log("render")
});
しかし、これは公式のリファレンスで推奨されていない書き方なので、使わないようにしましょう。
##第二引数を与える
###空の配列が渡されたとき
useEffect(() => {
console.log('mounting')
}, [])
第二引数に空の配列が渡された場合、マウント時のみ、第一引数に渡されたコールバック関数を実行します。
Reactはrenderが呼ばれるたびに第二引数の値がrender前とrender後に変化したかどうか
を確認します。
その時、変化していた場合にのみ第一引数に設定したコールバック関数を実行します。
今回は、第二引数に空の配列を指定しているため、マウント時のみ第一引数のコールバック関数が走るようになります。
componentDidMount
と同じタイミングになります。
###第二引数の配列に値が渡された場合
第二引数に値の配列が渡された場合、renderの前後で値が変化した場合
に第一引数のコールバック関数が呼ばれます。
const [boolean, changeBoolean] = useState(true)
useEffect(() => {
console.log('changed')
}, [boolean])
この場合、第二引数に渡したboolean
の値が変更されるたびに第一引数に渡したコールバック関数が呼ばれるようになります。
###マウント時とアンマウント時のみ実行
useEffectメソッドにおいては、第一引数のコールバック関数内においてreturnを行うと、そのreturnの中の処理がアンマウント時に実行されるようになります。
以下のコードです。
useEffect(() => {
console.log("render")
return () => {
console.log("Unmounting!")
}
}, []}
第二引数に空の配列を渡しているので、render毎に実行されることはありません。
つまり、console.log("render")
の部分がマウント時のみ実行されるようになります。
また、return後の関数が、アンマウント時に実行されるようになります。
#終わりに
今回の記事はここまでになります。
お疲れさまでした。
#参考