始めに
現在進行系でVueを学習中でありますが、reactとVueでは何が違うの?と考え勉強をはじめました。そこで、学習中のreact hooks勉強がてら復習していきます。
react hooksとは
componentでのデータ管理や監視を行ってくれるreactが備えたAPI
では実際に学習していきます。
useState
1, componentでもデータの状態管理を行う為に用いる
2, useStateを配列に分割代入し、data(変数),dataを更新する関数を設定する。
3, useState関数の引数はデフォルト値、空文字列や配列、オブジェクト、初期値は自由。実際に格納したいデータをイメージして設定する
実際にコードは下記のようになる。
//まずはuseStateを使えるようにimport
import React, {useState} from 'react';
const App = () => {
//useStateを定義..data名、メソッド名は任意の名称
const [data, setData] = useState("");
//stateの更新
const changeData = (e) => {
const changeData = e.target.value;
setData(changeData);
}
return(
<中略>
);
}
useEffect
1, componentでのデータ監視クを行う。
2, useEffect関数は第一引数にメソッドをとり、第二引数に配列をとる。
3, useEffectはjsxがrendingさた後に実行される。
Vueで考えると
/ 第二引数:なし
// 第一引数:レンダリング時に毎回呼ばれる
useEffect(() => {});
// 第二引数:空配列
// 第一引数:初回のレンダリング時のみ呼ばれる
// → つまり mounted と同等
useEffect(() => {}, []);
// 第二引数:中身のある配列
// 第一引数:配列で渡した変数のいずれかに変更があった場合のみ呼ばれる
useEffect(() => {}, [aaa, bbb]);
userの認証情報を保持する際に活用できそうです。
import React, {useState, useEffect} from 'react';
const App = () => {
//useStateを定義..data名、メソッド名は任意の名称
const [user, setUser] = useState({});
//useEffectを定義しstateの監視を行う
useEffect( () => {
const getUser = async () => {
const response = await axios.get('api/path');
setUser(reaponse)
}
}, [user]);
return(
<中略>
);
}
useReducer
1, componentにおけるデータ管理手段。useStateよりビジネスロジックが複雑な場合活用
2, useReducerの引数は第1引数にreducer(関数)、第2引数にinitialState(初期値)を受ける。reducerは「現在のstate」とactionを受け取り、stateのの更新を行う。state = 状態 action = 状態に対して変化をもたらすトリガー
import React, {useReducer} from 'react'
const initialState = 0
const reducer = (currentState, action) => {
// actionには、操作内容が入る
switch(action) {
case 'increment': // increment -> action
return currentState + 1
case 'decrement': // decrement -> action
return currentState - 1
case 'reset': // reset -> action
return initialState
default:
return currentState // どれにも当てはまらないとき
}
}
const App = () => {
const [count, dispatch] = useReducer(reducer, initialState)
return (
<div>
<div>Count {count}</div>
<button onClick={() => dispatch('increment')}>Increment</button>
<button onClick={() => dispatch('decrement')}>Decrement</button>
<button onClick={() => dispatch('reset')}>Reset</button>
</div>
)
}
useContext
1, use constext とは 親から子コンポーネント間でのデータ受け渡しを階層に関係なくデータを渡せる機能。
2, 基本的に親 → ひ孫にデータを渡す際は props を利用して親 → 子 → ひ孫といった流れでデータを渡していたが、useContext を利用することで親 → ひ孫と行った経路でデータを渡すことができる。
context 用の js ファイルを作成し管理、それを import する 下記の内容でひとまず OK
//contexts/AppContext.jsx
import { createContext } from 'react';
const AppContext = createContext();
export default AppContext;
親コンポーネントで usaeContext 定義したファイルをを使用できるようにする。そしてそれをコンポーネントタグとして活用する。
これでラップされたどこの階層のcomponentでもデータを受け取ることができる。
import AppContext from './contexts/AppContext';
const App = () => {
return() {
<>
//value属性として渡したいデータを登録。
<AppContext value={'this is useContex'}>
登録してる子のコンポーネントとか
</AppContext>
</>
}
}
データを受けたいコンポーネントで useContex を使用するように宣言する
useContext に渡す引数はコンテクストオブジェクト自体である。
import React, {useContext} from 'react';
cosnt Children = () => {
const value = useContex(AppContext);
return (
<>
//これでデータを受け取る子とることができる
<div>{value}</div>
</>
);
}
useReducer, contextApi, useContextを用いたglobalState管理
コンポーネント単位でpropsを使用せずデータを管理しようとすると、reduxが必要であったが、useContext,useReducerを使用することができる。
あくまでコンポーネント単位でのデータ一元管理はuseContext,useReduxer用いるが、規模が大きなるに連れて、reduxが必要になってくる。
- data管理にはData Storeを作成する。
- Data Storeはinital State, Reducer, ContextAPIを用いる。
- inital State → データの初期値。
- ProviderでラップしてやることでGlobal Stateをどこの階層でも読み込むことができる。
//Global stateの定義
//store/index.js
//initalState dataの初期化を行っている
const intialState = {
popular: []
};
//reducerによるデータ管理
const reducer = (state, action) => {
switch (action.type) {
case "SET_POPULAR":
return { popular: action.payload.popular };
default:
return state;
}
};
//global state importすることで各componentで使用しることもできる
export const Store = createContext({
globalState: intialState,
setGlobalState: () => null
});
//componentとして登録する。Providerでラップしデータを渡す。
// childern nodeを受けているので、import先でStoreProviderでラップすることで親要素を全て取得している。
const StoreProvider = ({ children }) => {
const [globalState, setGlobalState] = useReducer(reducer, intialState);
return (
<>
<Store.Provider value={{ globalState, setGlobalState }}>
{children}
</Store.Provider>
</>
);
};
登録先のコンポーネント
これでど階層でもuseContextを用いglobalState(state), setGlobalState(dispatch)を使用できるようになった
import React from "react";
import ReactDOM from "react-dom";
import StoreProvider from "./store/index";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<React.StrictMode>
<StoreProvider>
<App />
</StoreProvider>
</React.StrictMode>,
rootElement
);
useContextでreducerを使用できるようにしてみる
import React, { useContext, useState } from "react";
//storeをimport
import { Store } from "../store/index";
const Top = () => {
//Consumerを用いない代わりにuseContextを用いる
const { globalState, setGlobalState } = useContext(Store);
<>
<Layout>
<div>top page</div>
</Layout>
</>
);
};
export default Top;
終わりに
react hooksについて振り返りをしました。他にもhooksがあるので随時、学習ように更新していきます。