use〇〇を理解したい!!①
useState, useEffect…
use〇〇ってめっちゃ多いですよね。
全部覚えきれん!ってことで備忘録でまとめます
①はuseState,useEffect,useContext,useRef
②はuseReducer,useMemo,useCallbackをまとめる予定です。
もくじ
0.環境構築
1.useState
2.useEffect
3.useContext
4.useRef
5.さいごに
環境構築
テキトーにフォルダ作って、create-react-app
でやってもいいのですが、
練習用で、より軽量なビルドツール「vite」をご教授いただいたので使ってみます。
フォルダを作り、フォルダ内に入ります。
create-react-app
を打つところで、npm create vite@latest
を打ちます。
「プロジェクト名」を打つと何を起動するか聞かれるので、「React」を選択します。
「JS」「TS」どちらか選べと言われるので、好きな方を選ぶ。
これでプロジェクトが出来上がるので、
出来上がったプロジェクト内に移動してnpm i
で必要なモジュールをインポートして完了!
create-react-appはnpm start
で起動しましたが、Viteはnpm run dev
で起動します。
localhost:5173
に接続し、初期画面が出ればOKです。
usestate
ざっくりいうと「状態が変化したら何かするよ」ってやつです。
import { useState } from 'react';
import './App.css'
function App() {
const [count, setCount] = useState(0);
return (
<div className="App">
<h1>useStateを理解するよ</h1>
<p>{count}</p>
</div>
)
}
export default App
現在は以下の画面になっているかと思います。
今「0」が入っている「count」の数字を変化させたい!!
のような、現状を変化させたいときに使えるのがuseState
です。
やり方としては、count
に対し、別の値をsetCount
でセットします。
今回はボタンを作り、ボタンが押されたときにcount
を+1するようにしました。
+ボタンをクリックすると値が増えていきます。
import { useState } from 'react';
import './App.css'
function App() {
const [count, setCount] = useState(0);
return (
<div className="App">
<h1>useStateを理解するよ</h1>
<button onClick={() => setCount((prevState) => prevState + 1)}>+</button>
<p>{count}</p>
</div>
)
}
export default App
このように、現在の状態を変えたい場合にはuseState
を使用すると便利です。
useeffect
useEffect
は発火のタイミングを決めることができます。
「画面を再レンダリングしたときになんかする」「countがレンダリングされたときに何かする」のような、「何か起こったときにどうするか」を決めることができます。
タイミングはuseEffectの第二引数で決めることができます。
・何も指定しない→毎回のレンダリングを検知
・空の配列を指定→最初の一回のみレンダリングを検知
・値を指定→値がレンダリングされるごとに検知
以下は空の配列を指定していますので、画面をリロードしたときにコンソールに「れんだりんぐ!」が表示されます。
最初の一回のみ検知なので、再度画面をリロードする以外は「れんだりんぐ!」は追加で出ません。
import { useEffect, useState } from 'react';
import './App.css'
function App() {
const [count, setCount] = useState(0);
const handleClick = () => { setCount((prevState) => prevState + 1) };
useEffect(() => {
console.log('れんだりんぐ!');
}, []);
return (
<div className="App">
<h1>useStateを理解するよ</h1>
<button onClick={handleClick}>+</button>
<p>{count}</p>
<h1>useEffectを理解するよ</h1>
</div>
)
}
export default App
ちなみに、本来「れんだりんぐ!」は1回のみですが、ReactのStrictMode
の仕様上、2回出てしまいます。
Build後は一回しか出ませんのでこのままで問題ありません。
▽第二引数にcountを指定してみました。countの値がレンダリング(=変化)するごとに「れんだりんぐ!」が出ます。今回はuseStateで+ボタンを押すとcountの値を変化させるようにしているので、+を押すごとに「れんだりんぐ!」が出ます。
import { useEffect, useState } from 'react';
import './App.css'
function App() {
const [count, setCount] = useState(0);
const handleClick = () => { setCount((prevState) => prevState + 1) };
useEffect(() => {
console.log('れんだりんぐ!');
}, [count]);
return (
<div className="App">
<h1>useStateを理解するよ</h1>
<button onClick={handleClick}>+</button>
<p>{count}</p>
<h1>useEffectを理解するよ</h1>
</div>
)
}
export default App
usecontext
ざっくり言うと、「どこでも使える変数を定義する」役割です。
APPで宣言した変数をTodoで使用したい場合は、APP→Todos→Todoと、
propsを使用して、上からバケツリレーのように下まで降ろしていく方法があります。
これだとめんどくさい!ってことでuseContextを使用することで簡略化できます。
APPで宣言した変数をuseContextに格納し、それを読み込むことでどこからでも呼び出せます。
実際にやっていきましょう。
今回の頂点はmain.jsx
なので、そこで宣言したものを一番下のTodoで使用できるようにします。
とりあえずTodos
とTodo
を作って…
import './App.css'
import Todos from './todos';
function App() {
return (
<div className="App">
<h1>useContextを理解するよ</h1>
<Todos />
</div>
)
}
export default App
```Todos.tsx
import Todo from './Todo'
const Todos = () => {
return (
<div>Todos
<Todo />
</div>
)
}
export default Todos
import Todo from './Todo'
const Todos = () => {
return (
<div>Todos
<Todo />
</div>
)
}
export default Todos
const Todo = () => {
return (
<div>Todo</div>
)
}
export default Todo
準備ができたので、main.tsx
にuseContextを書いていきます。
今回は「nakanishiInfo」という情報をどこでも使えるようにします。
createContext
という関数を使い、全体で使用できる情報を定義し、「NakanishiInfoContext」に入れました。
この「NakanishiInfoContext」をグローバルに使用するには、使いたい範囲を<NakanishiInfoContext.Provider>
で囲みます。
value
の値には使いたい情報を入れます。(今回はnakanishiInfo)
import React, { createContext, useContext } from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'
const nakanishiInfo = {
name: 'nakanishi',
age: 120,
height: 350,
}
const NakanishiInfoContext = createContext(nakanishiInfo);
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<NakanishiInfoContext.Provider value={nakanishiInfo}>
<React.StrictMode>
<App />
</React.StrictMode>
</NakanishiInfoContext.Provider>
)
export default NakanishiInfoContext;
これで囲まれた「App」というコンポーネント、及びその配下のコンポーネント(Todos,Todo)でnakanishiInfoが使用できるようになりました。
あとは使いたいコンポーネントでインポートして使用するだけです。
今回はTodoでインポートして使用します。
import { useContext } from "react"
import NakanishiInfoContext from "./main";
const Todo = () => {
const nakanishiInfo = useContext(NakanishiInfoContext);
return (
<div>Todo
<p>{nakanishiInfo.name}</p>
<p>{nakanishiInfo.age}</p>
<p>{nakanishiInfo.height}</p>
</div>
)
}
export default Todo
▽無事にnakanishiInfo
の情報を受け渡すことができました。
useContext
の中身を確認したい場合は根本まで一階数ずつ戻る必要がなく、
根本に飛んで確認するだけになるので、かなり効率が良くなります。
useref
ざっくり言うと、変化を読み取って何かするときに使います。
変化を読み取りたい対象にref
を付け、監視することができます。
▽inputにref
を付けることで、中身を監視しています。
ボタンにonclickを付けて、ボタンが押されたときにinputの中身を表示するようにしています。
import { useRef } from 'react';
import './App.css'
function App() {
const ref = useRef();
const handleRef = () => {
console.log(ref);
}
return (
<div className="App">
<h1>useRefを理解するよ</h1>
<input type='text' ref={ref} />
<button onClick={handleRef}>ぼたん</button>
<p>{a}</p>
</div>
)
}
▽ref
で取り出したinputの中身を確認してみると、currentの中にvalueやassetなど、沢山の要素が入っていることが確認できます。
valueの値を取得したい場合は、handleRef
の中身をconsole.log(ref)
からconsole.log(ref.current.value)
に変更すればOKです。
▽読み取った情報をuseStateでセットしています。
何か入力してボタンを押すと、その内容で<p>{a}</p>
が更新されます。
import { useRef, useState } from 'react';
import './App.css'
function App() {
const ref = useRef();
const [a, setA] = useState('a');
const handleRef = () => {
setA(ref.current.value);
}
return (
<div className="App">
<h1>useRefを理解するよ</h1>
<input type='text' ref={ref} />
<button onClick={handleRef}>ぼたん</button>
<p>{a}</p>
</div>
)
}
さいごに
とりあえずよく使う4つをまとめました。
他のuse〇〇は②でまとめる予定です!!
最後までお読みいただき、ありがとうございました