Context
基本的な例
アクティブなテーマを含むコンテキストを作成する基本的な例を以下に示します。
import { createContext } from "react";
type ThemeContextType = "light" | "dark";
const ThemeContext = createContext<ThemeContextType>("light");
コンテキストを必要とするコンポーネントをコンテキストプロバイダーでラップします
import { useState } from "react";
const App = () => {
const [theme, setTheme] = useState<ThemeContextType>("light");
return (
<ThemeContext.Provider value={theme}>
<MyComponent />
</ThemeContext.Provider>
);
};
useContext
を呼び出して、コンテキストを読み取ったりサブスクライブしたりします。
import { useContext } from "react";
const MyComponent = () => {
const theme = useContext(ThemeContext);
return <p>The current theme is {theme}.</p>;
};
default context valueなし
意味のあるデフォルト値がない場合は、null
を指定します。
import { createContext } from "react";
interface CurrentUserContextType {
username: string;
}
const CurrentUserContext = createContext<CurrentUserContextType | null>(null);
const App = () => {
const [currentUser, setCurrentUser] = useState<CurrentUserContextType>({
username: "filiptammergard",
});
return (
<CurrentUserContext.Provider value={currentUser}>
<MyComponent />
</CurrentUserContext.Provider>
);
};
コンテキストの型がnull
になる可能性があるため、username
プロパティにアクセスしようとすると、'currentUser' is possibly 'null'
というTypeScriptエラーが発生することに注意してください。username
にアクセスするにはオプションチェーニングを使用できます。
import { useContext } from "react";
const MyComponent = () => {
const currentUser = useContext(CurrentUserContext);
return <p>Name: {currentUser?.username}.</p>;
};
ただし、コンテキストがnull
にならないことはわかっているので、null
をチェックしないようにするほうが望ましいです。これを行う1つの方法は、コンテキストが提供されていない場合にエラーがスローされるコンテキストを使用するカスタムフックを提供することです。
import { createContext } from "react";
interface CurrentUserContextType {
username: string;
}
const CurrentUserContext = createContext<CurrentUserContextType | null>(null);
const useCurrentUser = () => {
const currentUserContext = useContext(CurrentUserContext);
if (!currentUserContext) {
throw new Error(
"useCurrentUser has to be used within <CurrentUserContext.Provider>"
);
}
return currentUserContext;
};
これを実装時に、ランタイムの型の確認を使用すると、コンポーネントをプロバイダーが適切にラップしていないときに、コンソールに明確なエラーメッセージが表示されるという利点があります。これで、null
をチェックすることなくcurrentUser.username
にアクセスできます。
import { useContext } from "react";
const MyComponent = () => {
const currentUser = useCurrentUser();
return <p>Username: {currentUser.username}.</p>;
};
タイプアサーションを代替として
null
をチェックするのを避けるもう1つの方法は、コンテキストがnull
ではないことをTypeScriptに伝えるタイプアサーションを使用することです。
import { useContext } from "react";
const MyComponent = () => {
const currentUser = useContext(CurrentUserContext);
return <p>Name: {currentUser!.username}.</p>;
};
別のオプションは、デフォルト値として空のオブジェクトを使用し、予想されるコンテキストの型にキャストすることです。
const CurrentUserContext = createContext<CurrentUserContextType>(
{} as CurrentUserContextType
);
非nullアサーションを使用して同じ結果を得ることもできます。
const CurrentUserContext = createContext<CurrentUserContextType>(null!);
何をすべきかわからない場合は、タイプアサーションよりもランタイムチェックとスローを行います。