こう 聞かれます
- 「props の
バケツリレーとは 何ですか。 どう 解決しますか」 - 「Context は
どんな ときに 使いますか」 - 「何でも Context に
入れてはいけないのは なぜですか」
面接官が 見ている点
- バケツリレーの
困る 所 (途中の 部品が 使わない props を 受け渡す) を言えるか - Context に
飛びつく 前に、 children で 渡す組み方の 見直しを 挙げられるか - Context に
向く 値 (テーマ、 ログインしている 人、 言語など ) を 挙げられるか - Context の
値が 変わると、 使っている 部品が 全部描き直されると 知っているか
短い答え
- Context は、
親の 部品が 置いた 値を、間の 部品を 通さずに、 その 下の どの 深さの 部品から でも useContext で 読めるように する 仕組みです。 バケツリレーは、 深い所の 部品に 値を 届ける ために、 使わない 途中の 部品にも props を 通していく 状態です。 途中の 部品が 関係ない props を 抱え、 変更の たびに 何か所も 直すことになります。 - まずは
部品の 組み方を 見直し、 値を 使う 部品を 親で 組み立て、 children や JSX を 受け取る props として 渡して、 途中を 通さずに 渡せないかを 考えます。 - それでも
多くの 部品が 使う値、 たとえば テーマ、 ログインしている 人、 表示の 言語などは Context に 置き、 使う 部品が useContext で 直接読みます。
この
少し 詳しい答え
バケツリレーの例
TypeScript (JSX)
function App() {
const user = useCurrentUser();
return <Layout user={user} />; // Layout は user を使わない
}
function Layout({ user }: { user: User }) {
return <Header user={user} />; // Header も使わず、さらに下へ
}
function Header({ user }: { user: User }) {
return <Avatar user={user} />; // ここで初めて使う
}2、
組み方の見直し
途中の
TypeScript (JSX)
function App() {
const user = useCurrentUser();
return (
<Layout header={<Header avatar={<Avatar user={user} />} />}>
<Main />
</Layout>
);
}Avatar を
Context を使う
TypeScript (JSX)
const ThemeContext = createContext<"light" | "dark">("light");
function App() {
const [theme, setTheme] = useState<"light" | "dark">("light");
return (
<ThemeContext value={theme}>
<Page />
</ThemeContext>
);
}
function Button() {
const theme = useContext(ThemeContext); // 何段下でも直接読める
return <button className={theme}>保存</button>;
}React 19 からは ThemeContext を
注意
- Context の
値が 変わると、 その Context を 読む部品は 全部描き直されます。 頻繁に 変わる 値と、 ほとんど 変わらない 値は 別の Context に分けます - value に
毎回新しい オブジェクトを 作って 渡すと、 中身が 同じでも 全部が 描き直されます。 必要なら useMemo で覚えます - どこから
でも 読める 分、 値の 出どころが 追いにくくなります。 何でも 入れる 置き場にしません
よく ある間違い
- 2 段の
バケツリレーでも Context にする props で 渡すほうが 流れが 見えます。 困ってから使います - よく
変わる 値と 変わらない 値を 1 つの Context にまとめる 1 つ 変わる たびに、 関係ない 部品まで 描き直されます - サーバーから
取った データを 全部 Context に置く 取り直しや キャッシュの 管理を 自分で 抱えます。 データ取得の 道具に任せます
深掘りの問い
- 「Context と Redux や Zustand の違いは」 Context は
値を 届ける 仕組みで、 更新の 仕方や 一部だけ 読む工夫は 持たない。 頻繁に 変わる 共有の state が 増えたら 状態管理の 道具を 考える、と答えます - 「Provider で
囲まれていない所で useContext すると」 createContext に 渡した 初めの 値が 返る、と答えます - 「Context の
値を 子から 変えたいときは」 state を 変える 関数も Context で 一緒に 渡す、と答えます
