React学習の順番|JavaScript→React→Next.jsが正解?
React学習の効果的な順番を解説。JavaScript基礎からReact、Next.jsまでの最適な学習ロードマップと各段階で必要なスキルを詳しく説明します。
みなさん、こんな悩みを抱えていませんか?
「React学習を始めたいけど、どこから手をつければいいの?」
「JavaScriptを完璧にしてからReactを始めるべき?」
「ReactとNext.js、どっちを先に学ぶべき?」
React学習の順番で迷うのは、あなただけではありません。 実際、多くの初心者が同じような疑問を抱いています。
この記事では、効率的なReact学習ロードマップを詳しく解説します。 あなたのレベルに合わせた最適な学習順序で、確実にReactスキルを身につけましょう!
結論:段階的に学習するのが最効率
最初に結論をお伝えします。 HTML/CSS → JavaScript基礎 → React基礎 → React応用 → Next.jsの順番が最も効率的です。
なぜこの順番なの?
よく「JavaScriptを完璧にマスターしてから」と考える人がいますが、これは実は非効率なんです。
❌ 間違った考え方
- JavaScriptを100%理解してからReactを始める
- すべての基礎を完璧にしてから次へ進む
- 一つずつ順番に完全制覇する
✅ 効率的な考え方
- 80%理解できたら次のステップへ
- 必要な部分から優先的に学ぶ
- 実践しながら知識を深める
実際、現役のReactエンジニアでも、JavaScriptのすべての機能を知っているわけではありません。 必要な部分を押さえて、実践で経験を積むのが一番の近道です。
学習者のレベル別アプローチ
あなたのレベルに応じて、学習の進め方を調整しましょう。
完全初心者の場合(12-16週間)
- HTML/CSS基礎: 2-4週間
- JavaScript基礎: 3-6週間
- React基礎: 4-8週間
- React応用: 3-6週間
プログラミング経験者の場合(8-10週間)
- Web技術復習: 1週間
- JavaScript基礎: 2-4週間
- React基礎: 2-4週間
- React応用: 2-6週間
- Next.js基礎: 1-2週間
他フレームワーク経験者の場合(4-6週間)
- React特有の概念理解: 1週間
- React実装パターン: 1週間
- Reactエコシステム: 1週間
- Next.js応用: 1-3週間
ステップ1: Web開発の基礎(2-4週間)
まずは、Web開発の土台となるHTML/CSSから始めましょう。 既に理解している人は、サッと復習して次に進んでください。
HTMLで覚えるべきこと
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React学習の準備</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<nav>
<ul>
<li><a href="#home">ホーム</a></li>
<li><a href="#about">概要</a></li>
<li><a href="#contact">お問い合わせ</a></li>
</ul>
</nav>
</header>
<main>
<section id="home">
<h1>メインタイトル</h1>
<p>内容の説明文</p>
</section>
</main>
<footer>
<p>© 2024 My Website</p>
</footer>
<script src="script.js"></script>
</body>
</html>
覚えるべきポイント
- セマンティックHTML(header, main, section, article, footer)
- フォーム要素(input, textarea, select, button)
- 基本的なメタデータ設定
React学習でHTMLの基礎は必須です。 JSXはHTMLに似ているので、ここで基礎を固めておきましょう。
CSSで覚えるべきこと
/* 基本的なリセットとレイアウト */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial, sans-serif';
line-height: 1.6;
color: #333;
}
/* Flexboxレイアウト(Reactでよく使う) */
nav ul {
display: flex;
list-style: none;
gap: 2rem;
}
main {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
/* レスポンシブデザイン */
@media (max-width: 768px) {
nav ul {
flex-direction: column;
gap: 1rem;
}
main {
padding: 1rem;
}
}
重要なポイント
- Flexboxレイアウト(Reactで頻繁に使用)
- レスポンシブデザインの基本
- CSS GridやCSSトランジション
ReactのスタイリングでCSSの知識は必須です。 特にFlexboxは、Reactコンポーネントのレイアウトで頻繁に使います。
ステップ2: JavaScript基礎(3-6週間)
ここが最も重要なステップです。 ただし、Reactに必要な部分を重点的に学びましょう。
絶対に覚えるべきJavaScript機能
変数とデータ型
// React学習で重要な変数宣言
let userName = "田中太郎";
const userAge = 25;
let isActive = true;
// オブジェクトと配列(Reactでよく使う)
const user = {
name: "田中太郎",
age: 25,
email: "tanaka@example.com"
};
const hobbies = ["読書", "映画鑑賞", "プログラミング"];
アロー関数(Reactで必須)
// 通常の関数
function greetUser(name) {
return `こんにちは、${name}さん!`;
}
// アロー関数(Reactでよく使う)
const greetUser = (name) => {
return `こんにちは、${name}さん!`;
};
// 短縮形
const greetUser = name => `こんにちは、${name}さん!`;
アロー関数は、Reactのイベントハンドラーで頻繁に使います。 必ず覚えておきましょう。
配列メソッド(Reactで超重要)
const numbers = [1, 2, 3, 4, 5];
// map(リストレンダリングで必須)
const doubledNumbers = numbers.map(num => num * 2);
console.log(doubledNumbers); // [2, 4, 6, 8, 10]
// filter(条件による絞り込み)
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4]
// find(特定の要素を検索)
const foundNumber = numbers.find(num => num > 3);
console.log(foundNumber); // 4
特にmap
は、Reactでリストを表示する時に必ず使います。
絶対にマスターしてください。
分割代入とスプレッド演算子
// 分割代入(React propsで頻繁に使用)
const user = { name: "田中太郎", age: 25 };
const { name, age } = user;
const hobbies = ["読書", "映画"];
const [firstHobby, secondHobby] = hobbies;
// スプレッド演算子(React状態更新で必須)
const originalUser = { name: "田中太郎", age: 25 };
const updatedUser = {
...originalUser,
age: 26,
city: "東京"
};
これらは、Reactの状態管理で毎日使う機能です。 理解するまで練習しましょう。
非同期処理(API連携で必要)
// Promise の基本
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// async/await(ReactでAPI呼び出しに使用)
async function fetchUserData(userId) {
try {
const response = await fetch(`/api/users/${userId}`);
const userData = await response.json();
return userData;
} catch (error) {
console.error('データ取得エラー:', error);
return null;
}
}
API連携は、実際のReactアプリで必須の機能です。 基本的な非同期処理を覚えておきましょう。
実践的な練習プロジェクト
JavaScript基礎の学習では、こんなものを作ってみてください。
// 計算機アプリ(DOM操作の練習)
class Calculator {
constructor() {
this.display = document.getElementById('display');
this.currentInput = '0';
this.initializeEventListeners();
}
initializeEventListeners() {
document.querySelectorAll('.number').forEach(button => {
button.addEventListener('click', (e) => {
this.inputNumber(e.target.textContent);
});
});
}
inputNumber(num) {
this.currentInput = this.currentInput === '0' ? num : this.currentInput + num;
this.updateDisplay();
}
updateDisplay() {
this.display.textContent = this.currentInput;
}
}
// 初期化
document.addEventListener('DOMContentLoaded', () => {
new Calculator();
});
このレベルのJavaScriptが書けるようになったら、Reactに進みましょう。
ステップ3: React基礎(4-8週間)
いよいよReactの学習です! JavaScriptの基礎ができていれば、きっとスムーズに進められます。
まずはシンプルなコンポーネントから
// 最初のReactコンポーネント
function Welcome() {
return <h1>Reactへようこそ!</h1>;
}
// Propsを受け取るコンポーネント
function UserGreeting({ userName, isLoggedIn }) {
if (isLoggedIn) {
return <h2>おかえりなさい、{userName}さん!</h2>;
}
return <h2>ログインしてください</h2>;
}
// メインアプリ
function App() {
return (
<div>
<Welcome />
<UserGreeting userName="田中太郎" isLoggedIn={true} />
</div>
);
}
ポイント
- JSXの書き方(HTMLに似ているけど、少し違う)
- Propsでデータを受け渡し
- 条件分岐の表示
最初は「なんでHTMLがJavaScriptの中に?」と戸惑うかもしれません。 でも大丈夫、慣れればとても書きやすくなります。
useState でインタラクティブに
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
};
const decrement = () => {
setCount(count - 1);
};
return (
<div>
<p>カウント: {count}</p>
<button onClick={increment}>+1</button>
<button onClick={decrement}>-1</button>
</div>
);
}
理解のポイント
useState
は「状態」を管理するフックcount
は現在の値、setCount
は値を更新する関数- ボタンをクリックすると、画面が自動で更新される
これがReactの「リアクティブ」な部分です。 状態が変わると、自動で画面が更新されます。
リストの表示(map関数が活躍)
function TodoList() {
const [todos, setTodos] = useState([
{ id: 1, text: "Reactを学習する", completed: false },
{ id: 2, text: "コンポーネントを作る", completed: true },
{ id: 3, text: "アプリを完成させる", completed: false }
]);
const toggleTodo = (id) => {
setTodos(todos.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
));
};
return (
<ul>
{todos.map(todo => (
<li key={todo.id}>
<input
type="checkbox"
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
/>
<span style={{
textDecoration: todo.completed ? 'line-through' : 'none'
}}>
{todo.text}
</span>
</li>
))}
</ul>
);
}
重要なポイント
map
関数で配列をJSXに変換key
プロパティは必須(Reactが効率的に更新するため)- スプレッド演算子でオブジェクトを更新
ここで、JavaScript基礎で学んだmap
と分割代入が活躍します。
フォーム処理
function ContactForm() {
const [formData, setFormData] = useState({
name: '',
email: '',
message: ''
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData(prev => ({
...prev,
[name]: value
}));
};
const handleSubmit = (e) => {
e.preventDefault();
console.log('送信データ:', formData);
alert(`${formData.name}さん、メッセージありがとうございます!`);
setFormData({ name: '', email: '', message: '' });
};
return (
<form onSubmit={handleSubmit}>
<div>
<input
type="text"
name="name"
value={formData.name}
onChange={handleChange}
placeholder="名前"
required
/>
</div>
<div>
<input
type="email"
name="email"
value={formData.email}
onChange={handleChange}
placeholder="メールアドレス"
required
/>
</div>
<div>
<textarea
name="message"
value={formData.message}
onChange={handleChange}
placeholder="メッセージ"
required
/>
</div>
<button type="submit">送信</button>
</form>
);
}
フォーム処理は、実際のアプリでよく使う機能です。 この書き方をマスターしておきましょう。
useEffectでAPI連携
import { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchUser = async () => {
try {
setLoading(true);
// 模擬API呼び出し
await new Promise(resolve => setTimeout(resolve, 1000));
const userData = {
id: userId,
name: `ユーザー${userId}`,
email: `user${userId}@example.com`
};
setUser(userData);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
if (userId) {
fetchUser();
}
}, [userId]);
if (loading) return <div>読み込み中...</div>;
if (error) return <div>エラー: {error}</div>;
if (!user) return <div>ユーザーが見つかりません</div>;
return (
<div>
<h2>{user.name}</h2>
<p>メール: {user.email}</p>
<p>ID: {user.id}</p>
</div>
);
}
useEffectのポイント
- コンポーネントが表示された時に実行される
- 依存配列
[userId]
で「userIdが変わった時だけ実行」を指定 - 非同期処理でAPI呼び出し
この段階で、実用的なReactアプリが作れるようになります。
ステップ4: React応用(4-6週間)
基礎ができたら、より実践的な機能を学びましょう。
Context APIで状態を共有
import { createContext, useContext, useState } from 'react';
// ユーザー情報を共有するContext
const UserContext = createContext();
function UserProvider({ children }) {
const [user, setUser] = useState(null);
const login = (userData) => {
setUser(userData);
};
const logout = () => {
setUser(null);
};
return (
<UserContext.Provider value={{ user, login, logout }}>
{children}
</UserContext.Provider>
);
}
// カスタムフック
function useUser() {
const context = useContext(UserContext);
if (!context) {
throw new Error('useUser must be used within UserProvider');
}
return context;
}
// ヘッダーコンポーネント
function Header() {
const { user, logout } = useUser();
return (
<header>
{user ? (
<div>
<span>ようこそ、{user.name}さん</span>
<button onClick={logout}>ログアウト</button>
</div>
) : (
<div>ログインしてください</div>
)}
</header>
);
}
// メインアプリ
function App() {
return (
<UserProvider>
<Header />
{/* 他のコンポーネント */}
</UserProvider>
);
}
Context APIを使うと、深い階層のコンポーネント間でデータを共有できます。
useReducerで複雑な状態管理
import { useReducer } from 'react';
// 状態の更新ルールを定義
const todoReducer = (state, action) => {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
id: Date.now(),
text: action.payload,
completed: false
}
];
case 'TOGGLE_TODO':
return state.map(todo =>
todo.id === action.payload
? { ...todo, completed: !todo.completed }
: todo
);
case 'DELETE_TODO':
return state.filter(todo => todo.id !== action.payload);
default:
return state;
}
};
function TodoApp() {
const [todos, dispatch] = useReducer(todoReducer, []);
const addTodo = (text) => {
dispatch({ type: 'ADD_TODO', payload: text });
};
const toggleTodo = (id) => {
dispatch({ type: 'TOGGLE_TODO', payload: id });
};
const deleteTodo = (id) => {
dispatch({ type: 'DELETE_TODO', payload: id });
};
return (
<div>
<TodoForm onAdd={addTodo} />
<TodoList
todos={todos}
onToggle={toggleTodo}
onDelete={deleteTodo}
/>
</div>
);
}
useReducerは、複雑な状態の更新ルールを整理できます。
カスタムフックで再利用性を高める
// ローカルストレージと連携するカスタムフック
function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error('localStorage取得エラー:', error);
return initialValue;
}
});
const setValue = (value) => {
try {
setStoredValue(value);
window.localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error('localStorage保存エラー:', error);
}
};
return [storedValue, setValue];
}
// 使用例
function Settings() {
const [theme, setTheme] = useLocalStorage('theme', 'light');
return (
<div>
<h2>設定</h2>
<label>
<input
type="radio"
value="light"
checked={theme === 'light'}
onChange={(e) => setTheme(e.target.value)}
/>
ライトモード
</label>
<label>
<input
type="radio"
value="dark"
checked={theme === 'dark'}
onChange={(e) => setTheme(e.target.value)}
/>
ダークモード
</label>
</div>
);
}
カスタムフックを作ると、ロジックを再利用できます。
実践プロジェクト:天気アプリ
function WeatherApp() {
const [weather, setWeather] = useState(null);
const [loading, setLoading] = useState(false);
const [city, setCity] = useState('Tokyo');
const fetchWeather = async (cityName) => {
setLoading(true);
try {
// 実際のAPIの代わりにモックデータ
await new Promise(resolve => setTimeout(resolve, 1000));
const mockData = {
city: cityName,
temperature: Math.floor(Math.random() * 35) + 5,
condition: ['晴れ', '曇り', '雨'][Math.floor(Math.random() * 3)],
humidity: Math.floor(Math.random() * 100),
forecast: Array.from({ length: 5 }, (_, i) => ({
day: new Date(Date.now() + (i + 1) * 24 * 60 * 60 * 1000).toLocaleDateString(),
high: Math.floor(Math.random() * 35) + 5,
low: Math.floor(Math.random() * 20),
condition: ['晴れ', '曇り', '雨'][Math.floor(Math.random() * 3)]
}))
};
setWeather(mockData);
} catch (error) {
console.error('天気データ取得エラー:', error);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchWeather(city);
}, []);
return (
<div className="weather-app">
<h1>天気予報アプリ</h1>
<CitySelector
currentCity={city}
onCityChange={setCity}
onSearch={fetchWeather}
/>
{loading && <LoadingSpinner />}
{weather && !loading && (
<>
<CurrentWeather weather={weather} />
<WeatherForecast forecast={weather.forecast} />
</>
)}
</div>
);
}
この段階で、実用的なWebアプリが作れるようになります。
ステップ5: Next.js基礎(3-5週間)
Reactの基礎と応用ができたら、いよいよNext.jsです!
Next.jsって何?
Next.jsは、Reactをより実用的に使うためのフレームワークです。
Next.jsが解決する問題
- SEO対策(サーバーサイドレンダリング)
- ページ遷移の高速化
- 画像最適化
- API作成
ReactとNext.jsの違い
- React: ライブラリ(部品)
- Next.js: フレームワーク(完成された仕組み)
ページベースルーティング
// pages/index.js(ホームページ)
import Link from 'next/link';
export default function Home() {
return (
<div>
<h1>ホームページ</h1>
<nav>
<Link href="/about">
<a>アバウトページへ</a>
</Link>
<Link href="/blog">
<a>ブログページへ</a>
</Link>
</nav>
</div>
);
}
// pages/about.js(アバウトページ)
export default function About() {
return (
<div>
<h1>アバウトページ</h1>
<p>私たちについて</p>
</div>
);
}
// pages/blog/index.js(ブログ一覧)
export default function BlogIndex() {
return (
<div>
<h1>ブログ一覧</h1>
<ul>
<li><Link href="/blog/first-post"><a>最初の投稿</a></Link></li>
<li><Link href="/blog/second-post"><a>2番目の投稿</a></Link></li>
</ul>
</div>
);
}
ファイル名がそのままURLになります。 とてもわかりやすいですね。
動的ルーティング
// pages/blog/[slug].js(動的な記事ページ)
import { useRouter } from 'next/router';
export default function BlogPost() {
const router = useRouter();
const { slug } = router.query;
return (
<div>
<h1>記事: {slug}</h1>
<p>この記事の内容...</p>
</div>
);
}
[slug].js
のような書き方で、動的なURLに対応できます。
データ取得(SSG/SSR)
// pages/posts.js
export default function Posts({ posts }) {
return (
<div>
<h1>記事一覧</h1>
{posts.map(post => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
<time>{post.date}</time>
</article>
))}
</div>
);
}
// 静的サイト生成(SSG)
export async function getStaticProps() {
// ビルド時にデータを取得
const posts = await fetchPosts();
return {
props: {
posts
},
revalidate: 60 // 60秒ごとに再生成
};
}
// サーバーサイドレンダリング(SSR)の場合
// export async function getServerSideProps() {
// // リクエストごとにデータを取得
// const posts = await fetchPosts();
//
// return {
// props: {
// posts
// }
// };
// }
使い分けのポイント
- SSG: 内容があまり変わらないページ(ブログ記事など)
- SSR: リアルタイムなデータが必要なページ(ユーザーダッシュボードなど)
API Routes
// pages/api/posts.js
export default function handler(req, res) {
if (req.method === 'GET') {
// 記事一覧を取得
const posts = [
{
id: 1,
title: "Next.js入門",
excerpt: "Next.jsの基本的な使い方",
date: "2024-01-01"
},
{
id: 2,
title: "React Hooks活用法",
excerpt: "React Hooksを効果的に使う方法",
date: "2024-01-02"
}
];
res.status(200).json(posts);
} else if (req.method === 'POST') {
// 新しい記事を作成
const { title, content } = req.body;
if (!title || !content) {
return res.status(400).json({
error: 'タイトルと内容は必須です'
});
}
const newPost = {
id: Date.now(),
title,
content,
date: new Date().toISOString().split('T')[0]
};
res.status(201).json(newPost);
} else {
res.setHeader('Allow', ['GET', 'POST']);
res.status(405).end(`Method ${req.method} Not Allowed`);
}
}
API Routesを使うと、バックエンドAPIも一緒に作れます。
実践プロジェクト:ブログサイト
// pages/index.js
import Head from 'next/head';
import Link from 'next/link';
export default function Home({ posts, categories }) {
return (
<>
<Head>
<title>Next.js ブログ</title>
<meta name="description" content="Next.jsで作成したブログサイト" />
</Head>
<main>
<h1>Next.js ブログへようこそ</h1>
<section>
<h2>最新記事</h2>
{posts.slice(0, 3).map(post => (
<article key={post.id}>
<h3>
<Link href={`/posts/${post.slug}`}>
<a>{post.title}</a>
</Link>
</h3>
<p>{post.excerpt}</p>
<time>{post.date}</time>
</article>
))}
</section>
<aside>
<h3>カテゴリ</h3>
<ul>
{categories.map(category => (
<li key={category.id}>
<Link href={`/category/${category.slug}`}>
<a>{category.name}</a>
</Link>
</li>
))}
</ul>
</aside>
</main>
</>
);
}
export async function getStaticProps() {
const posts = await fetchPosts();
const categories = await fetchCategories();
return {
props: {
posts,
categories
},
revalidate: 3600 // 1時間ごとに更新
};
}
この段階で、本格的なWebサイトが作れるようになります。
よくある学習の落とし穴
多くの学習者がつまずくポイントと、その対策をご紹介します。
落とし穴1: 完璧主義
❌ 間違った考え方
- JavaScriptをすべて理解してからReactを始める
- 一つずつ完璧にマスターしてから次へ
- エラーが出ると諦めてしまう
✅ 正しい考え方
- 80%理解できたら次のステップへ
- 実践しながら理解を深める
- エラーは学習の機会と捉える
実践のコツ
// 完璧を求めすぎず、動くものを作る
function SimpleApp() {
const [count, setCount] = useState(0);
// 最初はこれだけでOK
return (
<div>
<p>カウント: {count}</p>
<button onClick={() => setCount(count + 1)}>
+1
</button>
</div>
);
}
// 慣れてきたら機能を追加
function EnhancedApp() {
const [count, setCount] = useState(0);
const [history, setHistory] = useState([]);
const increment = () => {
setCount(count + 1);
setHistory([...history, count + 1]);
};
return (
<div>
<p>カウント: {count}</p>
<button onClick={increment}>+1</button>
<div>
<h3>履歴</h3>
<ul>
{history.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
</div>
</div>
);
}
落とし穴2: チュートリアル地獄
❌ チュートリアル地獄の症状
- チュートリアルを完璧にコピーするだけ
- 理解せずに次のチュートリアルへ
- 自分でアプリを作ったことがない
- エラー解決の経験がない
✅ 脱出方法
- チュートリアルを改造してみる
- 機能を追加・変更してみる
- ゼロからアプリを作ってみる
実践例
// 元のTodoアプリ(チュートリアル通り)
function BasicTodoApp() {
const [todos, setTodos] = useState([]);
const [input, setInput] = useState('');
const addTodo = () => {
setTodos([...todos, { id: Date.now(), text: input, completed: false }]);
setInput('');
};
return (
<div>
<input value={input} onChange={(e) => setInput(e.target.value)} />
<button onClick={addTodo}>追加</button>
{todos.map(todo => (
<div key={todo.id}>{todo.text}</div>
))}
</div>
);
}
// 改造版(機能追加)
function EnhancedTodoApp() {
const [todos, setTodos] = useState([]);
const [input, setInput] = useState('');
const [filter, setFilter] = useState('all'); // 追加: フィルター
const [priority, setPriority] = useState('normal'); // 追加: 優先度
const addTodo = () => {
setTodos([...todos, {
id: Date.now(),
text: input,
completed: false,
priority, // 追加: 優先度
createdAt: new Date() // 追加: 作成日時
}]);
setInput('');
};
// 追加: フィルタリング機能
const filteredTodos = todos.filter(todo => {
if (filter === 'completed') return todo.completed;
if (filter === 'active') return !todo.completed;
return true;
});
return (
<div>
<div>
<input value={input} onChange={(e) => setInput(e.target.value)} />
<select value={priority} onChange={(e) => setPriority(e.target.value)}>
<option value="normal">普通</option>
<option value="high">重要</option>
</select>
<button onClick={addTodo}>追加</button>
</div>
{/* 追加: フィルターボタン */}
<div>
<button onClick={() => setFilter('all')}>すべて</button>
<button onClick={() => setFilter('active')}>未完了</button>
<button onClick={() => setFilter('completed')}>完了済み</button>
</div>
{filteredTodos.map(todo => (
<div key={todo.id} style={{
color: todo.priority === 'high' ? 'red' : 'black'
}}>
{todo.text}
</div>
))}
</div>
);
}
落とし穴3: 技術選択で迷いすぎる
❌ 迷いすぎる例
- CSS-in-JS vs CSS Modules vs Styled Components
- Redux vs Zustand vs Context API
- どのUIライブラリを使うべきか
✅ 段階的な技術選択
初心者段階
- CSS: CSS Modules または plain CSS
- 状態管理: useState + useContext
- UI: 自分で作成
- ビルドツール: Create React App
中級者段階
- CSS: Styled Components
- 状態管理: useReducer または Zustand
- UI: Material-UI または Chakra UI
- ビルドツール: Vite
上級者段階
- CSS: Tailwind CSS + Styled Components
- 状態管理: Redux Toolkit
- UI: カスタムデザインシステム
- ビルドツール: Webpack(カスタム設定)
最初は選択肢を絞って、確実にスキルを積みましょう。
効率的な学習リソース
各段階でおすすめの学習リソースをご紹介します。
公式ドキュメント活用法
初心者段階
- React公式チュートリアル(三目並べゲーム)
- React公式ドキュメントの「Main Concepts」
- 一つずつ確実に理解する
中級者段階
- Hooks に関する詳細ドキュメント
- Advanced Guides
- 実際のプロジェクトで活用しながら読む
上級者段階
- API Reference
- React Internals
- 必要に応じて詳細を確認
実践的な学習プラットフォーム
無料リソース
- freeCodeCamp(英語だが高品質)
- Codecademy React Course(基礎部分無料)
- YouTube(日本語コンテンツも豊富)
有料だが価値があるリソース
- Udemy React コース
- Pluralsight
- egghead.io
コミュニティ活用
日本語コミュニティ
- React Japan User Group
- Qiita のReactタグ
- Zenn のReact記事
国際コミュニティ
- React公式Discord
- Reddit r/reactjs
- Stack Overflow
学習の継続のコツ
小さな成功を積み重ねる
// 毎日少しずつでも進歩する
const learningProgress = {
day1: "HTMLの基本タグを覚えた",
day2: "CSSでFlexboxを使えるようになった",
day3: "JavaScriptのmapを理解した",
day4: "初めてのReactコンポーネントを作った",
day5: "useStateを使ったアプリを作った"
};
モチベーション維持の方法
- 学習の進捗を可視化する
- 作ったものを人に見せる
- 学習仲間を見つける
- 定期的に振り返りをする
まとめ:継続が一番の近道
React学習の効率的な順番について、詳しく解説しました。
重要なポイント
- 段階的学習: HTML/CSS → JavaScript → React → Next.js
- 80%ルール: 完璧を求めず、8割理解で次へ進む
- 実践重視: 理論だけでなく、必ず手を動かす
- 継続が鍵: 毎日少しずつでも続ける
学習成功の秘訣
- 完璧主義を避ける: 動くものを作ることを優先
- チュートリアル地獄を避ける: 必ず改造・拡張する
- 技術選択で迷いすぎない: 段階的に選択肢を増やす
- コミュニティを活用: 一人で悩まず質問する
学習期間の目安
- 完全初心者: 12-16週間で基礎習得
- プログラミング経験者: 8-10週間で応用まで
- 他フレームワーク経験者: 4-6週間でNext.jsまで
React学習は確かに時間がかかりますが、正しい順序で学習すれば必ずマスターできます。 焦らず、自分のペースで着実に進んでいきましょう。
今日から、あなたのReact学習ジャーニーを始めてみませんか? きっと3ヶ月後には、「Reactが書けるようになった!」と実感できるはずです。