useContextについて知る
React
Context とは何か?
状態を受け渡しするにはコンポーネント間で親コンポーネントから子コンポーネントへ props を用いて受け渡しを行うことができます。
しかしこうした状態のバケツリレーでは多くのコンポーネント間で状態の受け渡しが発生する場合に頓挫になってしまう場合があります。
Contextはある状態をいろんなコンポーネントから共有できるようにすることです。
Contextを用いることでpropsによる値のバケツリレーを使わずに、いろんなコンポーネントからアクセスできるグローバルな状態を定義することができます。
グローバルに定義する状態の例としては、認証情報やダーク、ライトといったテーマの情報などがあげられます。
useContext とは何か?
useContext は Context を使用するための ReactHooks です。
useContext を使うことでグローバルな状態を定義でき、いろんなコンポーネントからその状態にアクセスできるようになります。
useContext を使う手順
useContext を使うには下記の通りです。
①React.createContext で Context を作成する
②ContextProvider の value に状態を設定して子コンポーネントを囲う
③子コンポーネントから useContext を使用して定義した状態にアクセスする
useContext を使った例
useContext を使用してユーザー情報を更新するフォームを作成してみました。各ファイルの役割は以下の通りです。
- src/UserContextProvider.js -> Contextを定義
- src/App.js -> UserContextProviderを呼び出して子コンポーネントを囲う
- src/Profile.js -> Contextからユーザー情報を取得したり、更新したりする
src/UserContextProvider.js
import { useState, createContext } from "react";
export const UserContext = createContext();
function UserContextProvider({ children }) {
const [currentUser, setCurrentUser] = useState({ name: "taro", age: 25 }); // 本当は認証などを行う
return (
<UserContext.Provider value={{ currentUser, setCurrentUser }}>
{children}
</UserContext.Provider>
);
}
export default UserContextProvider;
src/App.js
import UserContextProvider from "./UserContextProvider";
import Profile from "./Profile";
function App() {
return (
<UserContextProvider>
<Profile />
</UserContextProvider>
);
}
export default App;
src/Profile.js
import React, { useContext, useState } from "react";
import { UserContext } from "./UserContextProvider";
function Profile() {
const { currentUser, setCurrentUser } = useContext(UserContext);
const [name, setName] = useState("");
const [age, setAge] = useState();
const handleSubmit = (e) => {
e.preventDefault();
setCurrentUser({
name: name,
age: age,
});
setName("");
setAge();
};
return (
<div>
<h2>現在のユーザー</h2>
<p>名前:{currentUser.name}</p>
<p>年齢:{currentUser.age}</p>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Name"
name="name"
onChange={(e) => setName(e.target.value)}
/>
<input
type="number"
placeholder="Age"
name="age"
onChange={(e) => setAge(e.target.value)}
/>
<button>変更</button>
</form>
</div>
);
}
export default Profile;