はじめに
これまでにReactやGraphQLを学び、実際にアプリを作って記事にもしてきました。
ただ正直に言うと——「動くものは作れたけれど、なぜGraphQLとReactが一緒に語られるのか、その便利さを実感しきれていない」状態でした。
RESTとの違いは何となく知っていても、「実際にReactで開発するときにどんな風に効いてくるのか?」が腹落ちしていなかったのです。
この記事では、アプリをゼロから作らなくてもイメージできるように、文字多め+最小限のコード断片で 「GraphQLとReactの相性の良さ」 を整理していきます。
あわせて、RESTと比べたときの違いも丁寧に触れていきます。
ゴールは“写経”ではなく、“納得”です!
React編:なにをする道具?

Reactは「UIを部品に分けるためのライブラリ」
- 役割:画面(UI)をコンポーネントという小さな部品に分けて作る
- 価値:部品ごとに責務がはっきりする → 読みやすい、直しやすい、再利用しやすい
- 合言葉:部品化・状態・単方向データフロー
最小の書き方イメージ
コンポーネント(見た目とロジックの一まとまり):
function HelloMessage() {
return <p>こんにちは</p>;
}
解説
function HelloMessage() { ... }
これは「関数コンポーネント」と呼ばれる最も基本的なReactコンポーネントの書き方です。
関数名は必ず大文字で始める(HelloMessage)というルールがあります。小文字で始めるとただの関数扱いになってしまい、JSX内で呼び出せなくなるためです。return <p>こんにちは</p>;
関数の戻り値としてJSX(JavaScript XML)を返しています。<p>こんにちは</p>
は通常のHTMLに似ていますが、JavaScript内に直接書けるのがポイントです。
Reactでは、「コンポーネント=UI部品を返す関数」とまず理解しておくと良いです。
Props(外から渡す値)
function HelloMessage(props) {
return <p>こんにちは、{props.name}</p>;
}
// 呼び出し側
<HelloMessage name="Taro" />
解説
props
は「プロパティ」の略で、親コンポーネントから子コンポーネントに渡される値をまとめたオブジェクトです。{props.name}
の部分は、JavaScriptの変数展開です。JSX内では{}
を使ってJavaScriptの式を埋め込めます。- 呼び出し側で
<HelloMessage name="Taro" />
と書くと、props
の中に{ name: "Taro" }
が入ります。
Reactは「部品を組み合わせる」ライブラリなので、この Propsの仕組みがUIの再利用性を支える核になります。
State(中で変わる値)とイベント
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
いまの数: {count}
</button>
);
}
解説
import { useState } from "react";
Reactのフック(Hook)と呼ばれる機能を読み込んでいます。フックは関数コンポーネントに「状態」や「副作用処理」などの機能を追加する仕組みです。const [count, setCount] = useState(0);
useState
は「状態を作る」フックです。count
… 状態の値(初期値は0)setCount
… 状態を更新する関数
という2つのものが配列として返ってくるので、分割代入を使ってそれぞれに名前を付けています。
<button onClick={() => setCount(count + 1)}>
onClick
はクリック時に実行されるイベントハンドラ。setCount(count + 1)
と書くと、count
が1増えて再レンダリングされます。
Reactでは「状態が変わればUIが自動で更新される」ので、わざわざdocument.querySelectorやinnerTextのようにDOMを触る必要がありません。ここが一番の便利さです。
単方向データフロー(親→子)
function Parent() {
const [keyword, setKeyword] = useState("");
return (
<>
<SearchBox onChange={setKeyword} />
<ResultList query={keyword} />
</>
);
}
解説
- 親コンポーネントが
keyword
という状態を持ち、子コンポーネントに値や関数を渡しています。 <SearchBox onChange={setKeyword} />
- 子から入力イベントがあったときに、親の状態を更新するために
setKeyword
を渡しています。
- 子から入力イベントがあったときに、親の状態を更新するために
<ResultList query={keyword} />
- 親の状態(keywordの値)をそのまま渡しています。
Reactの世界では、データの流れは常に「親→子」です。
子から直接親を操作することはできず、代わりに「親が関数を渡す → 子がそれを呼ぶ」形を取ります。この「単方向データフロー」のルールのおかげで、状態の所在が明確になり、バグの原因が追いやすくなります。
Reactの実感ポイント
- DOM操作を自分で書かなくていい(状態が変わればUIが勝手に同期)
- 責務が分かれる(フォームはフォーム、一覧は一覧)
- 小さく分けて積み上げられる(部品を組み合わせる感覚)
GraphQL編:なにをする道具?

GraphQLは「欲しいデータだけを宣言して取る仕組み」
- 役割:APIからデータを取るときの“言語”(RESTの代替/補完)
- 価値:必要なフィールドだけを一度に取得 → 無駄が少なく、往復も減る
- 合言葉:スキーマ・クエリ・型安全
最小の書き方イメージ
欲しいデータを宣言するクエリ
(ここでは例として、GitHubユーザー検索用のコードを抜粋しています)
query SearchUsers($q: String!) {
search(query: $q, type: USER, first: 5) {
nodes {
... on User {
id
login
avatarUrl
}
}
}
}
解説
query SearchUsers($q: String!) { ... }
query
は「データを取得する操作」を意味します。SearchUsers
はクエリに付けた任意の名前(わかりやすくするためのラベル)。($q: String!)
は「変数の宣言」。$q
が変数名。String!
は型指定で「文字列が必須」という意味です。
search(query: $q, type: USER, first: 5)
- GitHub GraphQL APIの
search
フィールドを呼び出しています。 query: $q
で、先ほど宣言した変数$q
を渡しています。type: USER
は「ユーザーを探す」という指定。first: 5
は「最初の5件を取得する」という意味です。
- GitHub GraphQL APIの
nodes { ... on User { ... } }
nodes
の中には検索でヒットした要素が並びます。... on User
は「型条件付きフラグメント」と呼ばれ、User
型のデータが来た場合だけ以下を取得するという意味です。{ id, login, avatarUrl }
で欲しいフィールドを列挙。これだけが返ってきます。
GraphQLは「必要なフィールドだけ宣言する」のが最大の特徴。
「ユーザーの名前だけ欲しい」「画像URLも欲しい」といったニーズに応じてクエリを書き換えれば、その通りのデータが返ってきます。
変数を渡して実行
runQuery({
query: SearchUsers,
variables: { q: "torvalds" }
}).then(result => {
console.log(result.data.search.nodes);
});
解説
runQuery({ query: SearchUsers, variables: { q: "torvalds" } })
- 実際にはApollo ClientやRelayといったライブラリがこの役割を担います。
query
には先ほど書いたGraphQLクエリを指定。variables
に、クエリで宣言した$q
の値を与えています。ここでは"torvalds"
。
.then(result => { ... })
- 実行結果は
Promise
として返ってくるので、.then
で処理します。 result.data.search.nodes
に、先ほど指定したid
,login
,avatarUrl
が入った配列が格納されます。
- 実行結果は
RESTだと「/users?q=torvalds」のようにエンドポイントやクエリパラメータを叩きますが、GraphQLは「1つのエンドポイントに対してクエリ文+変数を送る」という考え方です。
これにより、エンドポイントの数が爆発せず、取得データも柔軟に制御できるというメリットがあります。
RESTと比べると?

REST
GET /users?query=torvalds
// サーバーが用意した固定の形で返る
GraphQL
POST /graphql
{
query: "... id login avatarUrl だけちょうだい ..."
}
GraphQLの実感ポイント
- 過剰取得が起きにくい
- 関連データを一発で取れる
- スキーマで「何が取れるか」が明示される
React × GraphQLはどう噛み合う?

役割分担がとても自然です。
- React:UIの部品化と状態管理(画面側)
- GraphQL:必要なデータの宣言と取得(データ側)
擬似コードのイメージ
function UserList({ keyword }) {
const { data, loading, error } = useQuery(SearchUsers, { variables: { q: keyword } });
if (loading) return <p>読み込み中...</p>;
if (error) return <p>エラー</p>;
return data.search.nodes.map(u => <UserItem key={u.id} user={u} />);
}
UIとデータ取得の責務がきれいに分かれる。
「UIはどう見せる?」「データは何が必要?」と整理しやすい。
どんなときにメリットが立つか?
- 小規模(検索して名前だけ表示) → RESTで十分
- 中規模(名前+アイコン+リポジトリ数など複数の関連データ) → GraphQLが効いてくる
- 大規模(一覧・詳細・条件検索などUIが複雑) → Reactの部品化+GraphQLの型安全性が効く
よくあるつまずきと抜け方
- 「動いたけど実感がない」
→ わざと「関連データをまとめて取りたい」状況を作るとGraphQLが光る - 「用語が多くて混乱」
→ Reactは「部品・状態・親→子」、GraphQLは「スキーマ・クエリ・型」だけ覚えればOK - 「コード全部を覚えようとして疲れる」
→ どの責務の話(UI or データ)かを切り分けて見る
まとめ
ReactとGraphQLを一緒に触ってみると、最初は「別々のもの」に見えるかもしれません。
でも実際に手を動かしてみると、だんだんこう感じるはずです。
- React=「UIの部品担当」。状態が変われば、自然と画面が変わってくれる。
- GraphQL=「データ取得担当」。欲しい形だけを、一度でピンポイントに持ってきてくれる。
この2つは役割が重ならず、まるで歯車のように噛み合います。UIを小さく分ければ分けるほど、「この部品に必要なデータ」が明確になる。
するとGraphQLのクエリもスッキリ短くなり、データの流れが頭の中でカチッと整理される。

僕自身も、ここまで記事を書いてやっと「あ、そういうことか」と腹落ちしてきました。
ただコードを追うだけではなく、「役割の違いと噛み合い」を意識することで、ReactとGraphQLの本当の便利さがじわっと実感できるようになると思います。
次のステップ
React、GraphQLの良さが理解できたところで、デモアプリを作って理解を深めてきましょう!
もっと徹底的に基本を理解したい方は、以下記事もおススメです!
コメントを残す