React の props のバケツリレーは、どう解決しますか。Context はいつ使いますか

使わない部品を何段も通して props を渡すのがバケツリレーで、まず部品の組み方 (children で渡す) を見直し、それでも多くの部品が使う値だけ Context に置く、と答える問い。Context の値が変わると使う部品が全部描き直される注意まで話します。

答えてみる

面接官に「React の props のバケツリレーは、どう解決しますか。Context はいつ使いますか」と聞かれたつもりで、答えを見る前に自分の言葉で答えます。

声に出して答えた人は「書かずに答えを見る」で開けます。

解説を読む

聞かれ方から関連するコースまで、この問いの解説を全部ここに置いています。

こう聞かれます

  • 「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、3 段なら props で十分で、データの流れが目で追えるのが良さです。困るのは、段が深く、同じ値をあちこちに届けるときです。

組み方の見直し

途中の部品が「中身を入れる枠」でよいなら、children や、JSX を受け取る props (下の例の header や avatar) で受け取る形にすると、値を通さずに済みます。

TypeScript (JSX)

function App() {
  const user = useCurrentUser();
  return (
    <Layout header={<Header avatar={<Avatar user={user} />} />}>
      <Main />
    </Layout>
  );
}

Avatar を組み立てるのは user を持っている App なので、Layout も Header も user を知らなくて済みます。

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 をそのまま囲みに使えます。それより前の版では ThemeContext.Provider と書きます。

注意

  • Context の値が変わると、その Context を読む部品は全部描き直されます。頻繁に変わる値と、ほとんど変わらない値は別の Context に分けます
  • value に毎回新しいオブジェクトを作って渡すと、中身が同じでも全部が描き直されます。必要なら useMemo で覚えます
  • どこからでも読める分、値の出どころが追いにくくなります。何でも入れる置き場にしません

よくある間違い

  • 2 段のバケツリレーでも Context にする props で渡すほうが流れが見えます。困ってから使います
  • よく変わる値と変わらない値を 1 つの Context にまとめる 1 つ変わるたびに、関係ない部品まで描き直されます
  • サーバーから取ったデータを全部 Context に置く 取り直しやキャッシュの管理を自分で抱えます。データ取得の道具に任せます

深掘りの問い

  • 「Context と Redux や Zustand の違いは」 Context は値を届ける仕組みで、更新の仕方や一部だけ読む工夫は持たない。頻繁に変わる共有の state が増えたら状態管理の道具を考える、と答えます
  • 「Provider で囲まれていない所で useContext すると」 createContext に渡した初めの値が返る、と答えます
  • 「Context の値を子から変えたいときは」 state を変える関数も Context で一緒に渡す、と答えます

出典

確認日 2026年10月28日書き手 小尾 知希 (講師)

技術面接問題の一覧へ戻る