React学習の前提条件 - JavaScript初心者が準備すべき5つの知識
React学習を始める前に必要なJavaScriptの基礎知識5つを詳しく解説。ES6構文、配列操作、非同期処理など、初心者が躓きやすいポイントを具体例付きで紹介します。
みなさん、「Reactを始めたいけど、準備はできてる?」と不安になったことはありませんか?
「JavaScriptの基礎は分かるけど、これでReactに挑戦して大丈夫?」と迷ったことはありませんか?
この記事では、React学習を成功させるために必要な5つのJavaScript知識を解説します。 難しそうに見えますが、実は段階的に学べば意外と身につけやすいんです。
一緒にReact学習の準備を整えて、スムーズなスタートを切りましょう!
なぜReact学習に前提知識が必要なのか
React学習でつまずく原因
多くの初心者が同じポイントでつまずいているのを知っていますか?
React学習が困難になる主な原因は以下の通りです:
- 新しい概念が多すぎる:コンポーネント、state、propsなど独特の概念
- JavaScriptとReactの区別:どちらの知識が必要かわからない
- エラーの原因特定:JavaScript由来かReact由来かの判断が困難
- 学習範囲の広さ:JSX、フック、ライフサイクルなど多岐にわたる
JavaScriptの基礎が不十分だと、これらがさらに困難になってしまいます。
適切な準備がもたらすメリット
前提知識をしっかり準備すると、こんな良いことがあります:
- 学習効率が上がる:React固有の概念に集中できる
- エラー解決が早くなる:問題の原因を特定しやすい
- 応用力が身につく:基礎があることで応用が利く
- 挫折を防げる:基本的なところで躓かない
投資した時間は必ず回収できますよ。
初心者がよく混乱するポイント
こんな混乱をしたことはありませんか?
- 構文エラー:ES6構文の理解不足によるエラー
- 配列操作:map、filterなどの配列メソッドが使えない
- 非同期処理:APIからのデータ取得で躓く
- オブジェクト操作:プロパティの取得や更新方法がわからない
これらは全てJavaScriptの基礎知識で解決できる問題です。
前提知識1:ES6の基本構文
アロー関数をマスターしよう
アロー関数は、React開発で最も頻繁に使う構文です。
基本的な書き方を見てみましょう。
// 従来の関数記法function greet(name) { return `こんにちは、${name}さん!`;}
// アロー関数記法const greet = (name) => { return `こんにちは、${name}さん!`;};
// 省略記法(1行の場合)const greet = (name) => `こんにちは、${name}さん!`;
従来の関数ではfunction
キーワードを使います。
アロー関数では=>
記号を使って、より短く書けます。
1行で書ける場合は、return
も省略できるんです。
Reactでの使用例を見てみましょう。
// コンポーネント内での使用const UserCard = ({ user }) => { const handleClick = () => { console.log(`${user.name}がクリックされました`); };
return ( <div onClick={handleClick}> <h3>{user.name}</h3> <p>{user.email}</p> </div> );};
// 配列のmap関数と組み合わせconst UserList = ({ users }) => { return ( <div> {users.map(user => ( <UserCard key={user.id} user={user} /> ))} </div> );};
コンポーネントの定義では、アロー関数がよく使われます。 イベントハンドラーでも、短く書けるので便利です。
users.map(user => ...)
の部分では、配列の各要素をコンポーネントに変換しています。
テンプレートリテラルで文字列を楽に作る
文字列の組み立てが劇的に楽になる機能です。
基本的な使い方を見てみましょう。
const name = "田中太郎";const age = 25;
// 従来の書き方const message1 = "名前: " + name + ", 年齢: " + age + "歳";
// テンプレートリテラルconst message2 = `名前: ${name}, 年齢: ${age}歳`;
// 複数行での使用const htmlTemplate = ` <div> <h1>${name}</h1> <p>年齢: ${age}歳</p> </div>`;
**バッククォート(`)**を使うのがポイントです。 **${変数名}**で、変数の値を文字列に埋め込めます。
複数行の文字列も、改行をそのまま書けて便利ですね。
Reactでの活用例を見てみましょう。
const Button = ({ type, children, disabled }) => { // クラス名の動的生成 const className = `button button--${type} ${disabled ? 'button--disabled' : ''}`; // スタイルの動的生成 const style = { backgroundColor: `var(--color-${type})`, cursor: disabled ? 'not-allowed' : 'pointer' };
return ( <button className={className} style={style} disabled={disabled}> {children} </button> );};
クラス名の動的生成で威力を発揮します。
button--${type}
の部分で、typeに応じてクラス名が変わります。
CSS変数の指定でも便利に使えますね。
分割代入で値を簡単に取り出す
オブジェクトや配列から値を取り出す便利な構文です。
オブジェクトの分割代入を見てみましょう。
const user = { id: 1, name: "田中太郎", email: "tanaka@example.com", age: 25};
// 従来の書き方const name = user.name;const email = user.email;
// 分割代入const { name, email } = user;
// デフォルト値の設定const { name, email, phone = "未設定" } = user;
**{ name, email }**と書くだけで、複数の値を一度に取り出せます。 デフォルト値も設定できるので、プロパティが存在しない場合も安心です。
Reactでの使用例を見てみましょう。
// propsの分割代入const UserProfile = ({ user, onEdit, onDelete }) => { const { name, email, age, avatar } = user; return ( <div className="user-profile"> <img src={avatar} alt={name} /> <h2>{name}</h2> <p>{email}</p> <p>年齢: {age}歳</p> <button onClick={onEdit}>編集</button> <button onClick={onDelete}>削除</button> </div> );};
// stateの分割代入const LoginForm = () => { const [formData, setFormData] = useState({ email: '', password: '' }); const { email, password } = formData; return ( <form> <input type="email" value={email} onChange={(e) => setFormData({...formData, email: e.target.value})} /> <input type="password" value={password} onChange={(e) => setFormData({...formData, password: e.target.value})} /> </form> );};
propsの分割代入では、({ user, onEdit, onDelete })
と書きます。
これで、props.userではなく、直接userと書けるようになります。
stateの分割代入でも、値の取り出しが簡単になりますね。
スプレッド演算子で配列・オブジェクトを展開
配列やオブジェクトの展開に使う便利な機能です。
基本的な使い方を見てみましょう。
// 配列のスプレッドconst numbers1 = [1, 2, 3];const numbers2 = [4, 5, 6];const allNumbers = [...numbers1, ...numbers2]; // [1, 2, 3, 4, 5, 6]
// オブジェクトのスプレッドconst user = { name: "田中", age: 25 };const updatedUser = { ...user, age: 26 }; // { name: "田中", age: 26 }
// 関数の引数として使用const max = Math.max(...numbers1); // Math.max(1, 2, 3) と同等
...配列名で配列の中身を展開できます。 ...オブジェクト名でオブジェクトのプロパティを展開できます。
既存のデータを変更せずに、新しいデータを作れるのがポイントです。
Reactでの重要性を見てみましょう。
const TodoApp = () => { const [todos, setTodos] = useState([]); // 新しいtodoの追加 const addTodo = (text) => { const newTodo = { id: Date.now(), text, completed: false }; setTodos([...todos, newTodo]); // 既存配列を変更せず新しい配列を作成 }; // todoの更新 const updateTodo = (id, updates) => { setTodos(todos.map(todo => todo.id === id ? { ...todo, ...updates } : todo )); }; return ( <div> {todos.map(todo => ( <div key={todo.id}> <span>{todo.text}</span> <button onClick={() => updateTodo(todo.id, { completed: !todo.completed })}> {todo.completed ? '未完了' : '完了'} </button> </div> ))} </div> );};
新しいtodoの追加では、[...todos, newTodo]
と書きます。
既存のtodos配列を変更せずに、新しい配列を作成しています。
todoの更新では、{ ...todo, ...updates }
でオブジェクトを更新します。
Reactの不変性の原則において、スプレッド演算子は必須の知識です。
前提知識2:配列操作メソッド
mapメソッドでリスト表示をマスター
React開発で最も重要な配列メソッドです。
基本的な使い方を見てみましょう。
const numbers = [1, 2, 3, 4, 5];
// 各要素を2倍にするconst doubled = numbers.map(num => num * 2);console.log(doubled); // [2, 4, 6, 8, 10]
// オブジェクトの配列を変換const users = [ { id: 1, name: "田中", age: 25 }, { id: 2, name: "佐藤", age: 30 }, { id: 3, name: "高橋", age: 35 }];
const userNames = users.map(user => user.name);console.log(userNames); // ["田中", "佐藤", "高橋"]
mapメソッドは、配列の各要素を変換して新しい配列を作ります。 元の配列は変更されないので、安心して使えます。
num => num * 2
の部分で、各数値を2倍にしています。
user => user.name
で、ユーザーオブジェクトから名前だけを取り出しています。
Reactでの必須使用パターンを見てみましょう。
const UserList = ({ users }) => { return ( <div className="user-list"> {users.map(user => ( <div key={user.id} className="user-card"> <h3>{user.name}</h3> <p>年齢: {user.age}歳</p> <p>メール: {user.email}</p> </div> ))} </div> );};
// より複雑な例const ProductList = ({ products, onAddToCart }) => { return ( <div className="product-grid"> {products.map(product => ( <div key={product.id} className="product-card"> <img src={product.image} alt={product.name} /> <h3>{product.name}</h3> <p className="price">¥{product.price.toLocaleString()}</p> <button onClick={() => onAddToCart(product)} className="add-to-cart-btn" > カートに追加 </button> </div> ))} </div> );};
ユーザーリストでは、users配列からJSXのリストを生成しています。 **key={user.id}**は、Reactがリストを効率的に更新するために必要です。
商品リストでは、より複雑なカードコンポーネントを生成しています。
onClick={() => onAddToCart(product)}
で、クリック時に商品をカートに追加できます。
Reactにおいて、配列からJSX要素のリストを生成する際の標準的な方法です。
filterメソッドで条件に合うデータを抽出
条件に合う要素のみを抽出するメソッドです。
基本的な使い方を見てみましょう。
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 偶数のみを抽出const evenNumbers = numbers.filter(num => num % 2 === 0);console.log(evenNumbers); // [2, 4, 6, 8, 10]
// オブジェクト配列のフィルタリングconst users = [ { id: 1, name: "田中", age: 25, active: true }, { id: 2, name: "佐藤", age: 30, active: false }, { id: 3, name: "高橋", age: 35, active: true }];
// アクティブなユーザーのみconst activeUsers = users.filter(user => user.active);
// 30歳以上のユーザーconst adultUsers = users.filter(user => user.age >= 30);
filterメソッドは、条件を満たす要素のみで新しい配列を作ります。
num % 2 === 0
で偶数かどうかを判定しています。
user => user.active
で、activeプロパティがtrueのユーザーのみを抽出。
user => user.age >= 30
で、30歳以上のユーザーを抽出しています。
Reactでの活用例を見てみましょう。
const SearchableUserList = ({ users }) => { const [searchTerm, setSearchTerm] = useState(''); const [filterActive, setFilterActive] = useState(false); // 検索とフィルタリングの組み合わせ const filteredUsers = users .filter(user => { // 名前での検索 const matchesSearch = user.name .toLowerCase() .includes(searchTerm.toLowerCase()); // アクティブユーザーフィルタ const matchesActive = filterActive ? user.active : true; return matchesSearch && matchesActive; }); return ( <div> <input type="text" value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} placeholder="ユーザー名で検索" /> <label> <input type="checkbox" checked={filterActive} onChange={(e) => setFilterActive(e.target.checked)} /> アクティブユーザーのみ表示 </label> <div className="user-list"> {filteredUsers.map(user => ( <div key={user.id} className="user-card"> <h3>{user.name}</h3> <p>年齢: {user.age}歳</p> <span className={`status ${user.active ? 'active' : 'inactive'}`}> {user.active ? 'アクティブ' : '非アクティブ'} </span> </div> ))} </div> <p>表示件数: {filteredUsers.length}件</p> </div> );};
検索機能では、user.name.toLowerCase().includes(searchTerm.toLowerCase())
を使います。
文字列を小文字に変換してから比較することで、大文字小文字を区別しない検索ができます。
フィルタリング機能では、チェックボックスの状態に応じて条件を変えています。
matchesSearch && matchesActive
で、両方の条件を満たすユーザーのみを表示。
動的なデータ表示で、filterメソッドは欠かせない機能です。
findメソッドで特定のデータを取得
特定の条件に合う最初の要素を取得するメソッドです。
基本的な使い方を見てみましょう。
const users = [ { id: 1, name: "田中", email: "tanaka@example.com" }, { id: 2, name: "佐藤", email: "sato@example.com" }, { id: 3, name: "高橋", email: "takahashi@example.com" }];
// IDで特定のユーザーを取得const user = users.find(user => user.id === 2);console.log(user); // { id: 2, name: "佐藤", email: "sato@example.com" }
// 見つからない場合はundefinedを返すconst notFound = users.find(user => user.id === 999);console.log(notFound); // undefined
findメソッドは、条件に合う最初の要素のみを返します。
見つからない場合はundefined
を返すので、注意が必要です。
filterメソッドとの違いは、1つの要素だけを返すことです。
Reactでの使用例を見てみましょう。
const UserDetail = ({ userId, users }) => { const user = users.find(u => u.id === parseInt(userId)); if (!user) { return <div>ユーザーが見つかりません</div>; } return ( <div className="user-detail"> <h2>{user.name}</h2> <p>メール: {user.email}</p> <p>年齢: {user.age}歳</p> </div> );};
// ショッピングカートでの使用例const ShoppingCart = ({ cart, products }) => { const cartItems = cart.map(cartItem => { const product = products.find(p => p.id === cartItem.productId); return { ...cartItem, product: product }; }); return ( <div className="shopping-cart"> {cartItems.map(item => ( <div key={item.id} className="cart-item"> <h3>{item.product.name}</h3> <p>数量: {item.quantity}</p> <p>価格: ¥{item.product.price * item.quantity}</p> </div> ))} </div> );};
ユーザー詳細では、userIdに基づいて特定のユーザーを取得します。
parseInt(userId)
で文字列を数値に変換しているのがポイントです。
ショッピングカートでは、カートアイテムと商品情報を組み合わせています。 cartには商品IDだけが入っているので、findで実際の商品情報を取得しています。
IDベースでのデータ取得でよく使用されるメソッドです。
前提知識3:オブジェクト操作
プロパティアクセスの方法
オブジェクトのプロパティにアクセスする方法を理解しましょう。
基本的なアクセス方法を見てみましょう。
const user = { id: 1, name: "田中太郎", email: "tanaka@example.com", address: { prefecture: "東京都", city: "渋谷区" }};
// ドット記法console.log(user.name); // "田中太郎"console.log(user.address.city); // "渋谷区"
// ブラケット記法console.log(user["name"]); // "田中太郎"console.log(user["address"]["city"]); // "渋谷区"
// 動的プロパティアクセスconst propertyName = "email";console.log(user[propertyName]); // "tanaka@example.com"
ドット記法は、プロパティ名が決まっている場合に使います。 ブラケット記法は、動的にプロパティ名を指定したい場合に便利です。
ネストしたオブジェクトでは、user.address.city
のように連続してアクセスできます。
オプショナルチェーニングで安全にアクセス
プロパティが存在するかわからない場合の安全なアクセス方法です。
const user = { id: 1, name: "田中太郎", // address プロパティが存在しない場合がある};
// 従来の書き方(エラーが発生する可能性)// console.log(user.address.city); // TypeError: Cannot read property 'city' of undefined
// 安全な書き方console.log(user.address && user.address.city); // undefined
// オプショナルチェーニング(推奨)console.log(user.address?.city); // undefined
**オプショナルチェーニング(?.)**を使うと、プロパティが存在しない場合でもエラーになりません。
user.address?.city
と書くだけで、安全にアクセスできます。
Reactでの使用例を見てみましょう。
const UserProfile = ({ user }) => { // userが存在しない場合の処理 if (!user) { return <div>ユーザー情報を読み込み中...</div>; } return ( <div className="user-profile"> <h2>{user.name}</h2> <p>メール: {user.email}</p> {/* 住所が存在する場合のみ表示 */} {user.address && ( <div className="address"> <h3>住所</h3> <p>{user.address.prefecture} {user.address.city}</p> {/* オプショナルチェーニングでより安全に */} <p>郵便番号: {user.address?.zipCode || '未設定'}</p> </div> )} {/* 配列プロパティの安全なアクセス */} {user.hobbies?.length > 0 && ( <div className="hobbies"> <h3>趣味</h3> <ul> {user.hobbies.map((hobby, index) => ( <li key={index}>{hobby}</li> ))} </ul> </div> )} </div> );};
条件付きレンダリングでは、user.address &&
でaddressが存在する場合のみ表示。
オプショナルチェーニングでは、user.address?.zipCode
で安全にアクセス。
配列の存在確認では、user.hobbies?.length > 0
で配列が存在し、かつ要素があるかを確認。
データの存在確認と安全なアクセスは、React開発で非常に重要です。
オブジェクトの不変更新
Reactにおけるstate更新では、オブジェクトの不変性を保つ更新方法が重要です。
基本的な更新パターンを見てみましょう。
const user = { id: 1, name: "田中太郎", email: "tanaka@example.com", settings: { theme: "light", notifications: true }};
// 浅い更新(スプレッド演算子使用)const updatedUser = { ...user, name: "田中次郎", email: "jiro@example.com"};
// 深い更新(ネストしたオブジェクト)const updatedUserWithSettings = { ...user, settings: { ...user.settings, theme: "dark" }};
浅い更新では、スプレッド演算子でオブジェクトを展開して、一部のプロパティを変更。 深い更新では、ネストしたオブジェクトも同様にスプレッド演算子で展開。
元のオブジェクトを変更せずに、新しいオブジェクトを作成することが重要です。
Reactでのstate更新を見てみましょう。
const UserSettingsForm = ({ initialUser }) => { const [user, setUser] = useState(initialUser); // 基本的なプロパティの更新 const updateName = (newName) => { setUser(prevUser => ({ ...prevUser, name: newName })); }; // ネストしたオブジェクトの更新 const updateTheme = (newTheme) => { setUser(prevUser => ({ ...prevUser, settings: { ...prevUser.settings, theme: newTheme } })); }; // 配列プロパティの更新 const addHobby = (hobby) => { setUser(prevUser => ({ ...prevUser, hobbies: [...(prevUser.hobbies || []), hobby] })); }; return ( <div className="user-settings"> <input type="text" value={user.name} onChange={(e) => updateName(e.target.value)} placeholder="名前" /> <select value={user.settings?.theme || 'light'} onChange={(e) => updateTheme(e.target.value)} > <option value="light">ライト</option> <option value="dark">ダーク</option> </select> </div> );};
基本的なプロパティ更新では、{ ...prevUser, name: newName }
と書きます。
ネストしたオブジェクト更新では、settingsオブジェクトも展開して更新。
配列プロパティ更新では、[...(prevUser.hobbies || []), hobby]
で新しい配列を作成。
|| []
で、hobbiesが存在しない場合のデフォルト値を設定しています。
不変性を保ったstate更新は、Reactの再レンダリング最適化において重要です。
前提知識4:非同期処理
Promiseの基本を理解しよう
React でAPI通信を行う際に必要な知識です。
Promiseの概念を見てみましょう。
// Promiseの基本形const fetchData = () => { return new Promise((resolve, reject) => { // 非同期処理のシミュレーション setTimeout(() => { const success = Math.random() > 0.3; // 70%の確率で成功 if (success) { resolve({ data: "取得したデータ" }); } else { reject(new Error("データの取得に失敗しました")); } }, 1000); });};
// Promiseの使用fetchData() .then(result => { console.log("成功:", result.data); }) .catch(error => { console.error("エラー:", error.message); });
Promiseは、非同期処理の結果を扱うための仕組みです。 resolveは成功時に呼ばれ、rejectは失敗時に呼ばれます。
thenで成功時の処理を、catchで失敗時の処理を書きます。
Promiseチェーンも見てみましょう。
const fetchUser = (id) => { return new Promise(resolve => { setTimeout(() => { resolve({ id, name: `ユーザー${id}` }); }, 500); });};
const fetchUserPosts = (userId) => { return new Promise(resolve => { setTimeout(() => { resolve([ { id: 1, title: "投稿1", userId }, { id: 2, title: "投稿2", userId } ]); }, 500); });};
// PromiseチェーンfetchUser(1) .then(user => { console.log("ユーザー:", user); return fetchUserPosts(user.id); }) .then(posts => { console.log("投稿:", posts); }) .catch(error => { console.error("エラー:", error); });
Promiseチェーンでは、thenの中でPromiseを返すことで、順次処理を行えます。 まずユーザー情報を取得してから、そのユーザーの投稿を取得しています。
async/awaitでより読みやすく
より読みやすい非同期処理の書き方です。
基本的な使い方を見てみましょう。
// async function として定義const fetchUserAndPosts = async (userId) => { try { // await で非同期処理の完了を待つ const user = await fetchUser(userId); console.log("ユーザー:", user); const posts = await fetchUserPosts(user.id); console.log("投稿:", posts); return { user, posts }; } catch (error) { console.error("エラー:", error); throw error; }};
// 使用例const loadData = async () => { try { const result = await fetchUserAndPosts(1); console.log("データ読み込み完了:", result); } catch (error) { console.error("データ読み込み失敗:", error); }};
async functionとして関数を定義します。 awaitで非同期処理の完了を待ちます。
同期処理のような書き方で、非同期処理を扱えるのが便利ですね。
Reactでの使用例を見てみましょう。
const UserProfile = ({ userId }) => { const [user, setUser] = useState(null); const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); // useEffect内でのasync/await使用 useEffect(() => { const loadUserData = async () => { try { setLoading(true); setError(null); // ユーザー情報の取得 const userData = await fetch(`/api/users/${userId}`); const user = await userData.json(); setUser(user); // 投稿情報の取得 const postsData = await fetch(`/api/users/${userId}/posts`); const posts = await postsData.json(); setPosts(posts); } catch (err) { setError(err.message); } finally { setLoading(false); } }; loadUserData(); }, [userId]); if (loading) return <div>読み込み中...</div>; if (error) return <div>エラー: {error}</div>; if (!user) return <div>ユーザーが見つかりません</div>; return ( <div className="user-profile"> <h2>{user.name}</h2> <p>{user.email}</p> <h3>投稿一覧</h3> <div className="posts"> {posts.map(post => ( <div key={post.id} className="post"> <h4>{post.title}</h4> <p>{post.content}</p> </div> ))} </div> </div> );};
useEffect内でasync関数を定義して呼び出します。 useEffectのコールバック自体をasyncにはできないので、内部で関数を定義するのがポイント。
fetch APIでデータを取得し、**json()**でJSONに変換します。 try-catch-finallyで、エラーハンドリングと後処理を適切に行います。
loading状態とerror状態を管理して、ユーザーに適切なフィードバックを提供。
React におけるデータフェッチングの標準的なパターンです。
前提知識5:モジュールシステム
import/exportでコードを分割管理
React開発では、コンポーネントや関数をモジュールとして分割管理します。
Named Export/Importを見てみましょう。
// utils.js - 複数の関数をエクスポートexport const formatDate = (date) => { return new Intl.DateTimeFormat('ja-JP').format(date);};
export const formatCurrency = (amount) => { return new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(amount);};
export const validateEmail = (email) => { const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return regex.test(email);};
// main.js - 必要な関数のみインポートimport { formatDate, formatCurrency } from './utils.js';
const now = new Date();console.log(formatDate(now)); // 2024/1/1console.log(formatCurrency(1000)); // ¥1,000
export constで関数をエクスポートします。 **import { 関数名 }**で必要な関数のみをインポートできます。
必要な機能のみを選択的にインポートできるのが便利ですね。
Default Export/Importも見てみましょう。
// Button.js - デフォルトエクスポートconst Button = ({ children, onClick, type = 'button' }) => { return ( <button type={type} onClick={onClick} className="btn"> {children} </button> );};
export default Button;
// App.js - デフォルトインポートimport Button from './components/Button.js';
const App = () => { return ( <div> <Button onClick={() => alert('クリック!')}> クリックしてください </Button> </div> );};
export defaultでメイン機能をエクスポートします。 import 名前でデフォルトエクスポートをインポートします。
1つのモジュールにつき1つのメイン機能をエクスポートする場合に使用します。
Reactでの実践的な活用
以下のようにReact開発で活用されます。
// components/UserCard.jsimport React from 'react';import { formatDate } from '../utils/dateUtils.js';import Button from './Button.js';
const UserCard = ({ user, onEdit, onDelete }) => { return ( <div className="user-card"> <h3>{user.name}</h3> <p>登録日: {formatDate(user.createdAt)}</p> <div className="actions"> <Button onClick={() => onEdit(user.id)}>編集</Button> <Button onClick={() => onDelete(user.id)}>削除</Button> </div> </div> );};
export default UserCard;
// pages/UserList.jsimport React, { useState, useEffect } from 'react';import UserCard from '../components/UserCard.js';import { fetchUsers, deleteUser } from '../api/userApi.js';
const UserList = () => { const [users, setUsers] = useState([]); useEffect(() => { const loadUsers = async () => { const userData = await fetchUsers(); setUsers(userData); }; loadUsers(); }, []); const handleDelete = async (userId) => { await deleteUser(userId); setUsers(users.filter(user => user.id !== userId)); }; return ( <div className="user-list"> {users.map(user => ( <UserCard key={user.id} user={user} onEdit={(id) => console.log(`編集: ${id}`)} onDelete={handleDelete} /> ))} </div> );};
export default UserList;
UserCardコンポーネントでは、utilities関数とButtonコンポーネントをインポート。 UserListページでは、UserCardコンポーネントとAPI関数をインポート。
各ファイルの責任が明確になり、再利用しやすくなります。
コンポーネントの分割と再利用により、保守性の高いコードが書けます。
学習の進め方とチェックリスト
段階的な学習アプローチ
効率的に前提知識を習得する方法をお伝えします。
学習の優先順位は以下の通りです:
第1週: ES6基本構文
- アロー関数の理解と練習
- テンプレートリテラルの活用
- 分割代入の習得
- スプレッド演算子の理解
第2週: 配列操作
- mapメソッドの習得
- filterメソッドの理解
- findメソッドの活用
- 複数メソッドの組み合わせ
第3週: オブジェクト操作
- プロパティアクセス方法
- オプショナルチェーニング
- オブジェクトの不変更新
- 実践的な練習
第4週: 非同期処理とモジュール
- Promiseの基本理解
- async/awaitの習得
- import/exportの活用
- 総合的な練習
段階的に学習することで、無理なくスキルを身につけられます。
実践的な練習方法
以下のような方法で実践的に学習しましょう:
コード写し
- 記事のサンプルコードを正確に写す
- 動作を確認して理解を深める
- 少しずつ改変して実験する
ミニプロジェクト
- todoリストの作成(配列操作の練習)
- ユーザー管理システム(オブジェクト操作)
- 天気アプリ(非同期処理の練習)
オンライン練習
- CodePenでの実験
- JSFiddleでのコード試行
- ブラウザの開発者ツールでの実行
継続的な練習が重要です。
React学習開始の判断基準
以下のチェックリストで準備状況を確認しましょう。
ES6構文のチェック □ アロー関数を自然に書ける □ テンプレートリテラルで文字列を組み立てられる □ 分割代入でオブジェクトから値を取り出せる □ スプレッド演算子で配列・オブジェクトを展開できる
配列操作のチェック □ mapメソッドで配列を変換できる □ filterメソッドで配列をフィルタリングできる □ findメソッドで特定要素を取得できる □ 複数メソッドを組み合わせて使える
オブジェクト操作のチェック □ ドット記法とブラケット記法を使い分けられる □ オプショナルチェーニングで安全にアクセスできる □ スプレッド演算子でオブジェクトを更新できる □ ネストしたオブジェクトを適切に更新できる
非同期処理のチェック □ Promiseの基本概念を理解している □ async/awaitで非同期処理を書ける □ try/catchでエラーハンドリングができる □ 複数の非同期処理を組み合わせられる
モジュールシステムのチェック □ import/export文を書ける □ default exportとnamed exportを使い分けられる □ 他ファイルの機能を適切にインポートできる
これらの項目が80%以上理解できていれば、React学習を開始できます。
まとめ
React学習を成功させるために、5つの重要なJavaScript知識を解説しました。
5つの必要な前提知識をおさらいしましょう:
- ES6の基本構文:アロー関数、テンプレートリテラル、分割代入、スプレッド演算子
- 配列操作メソッド:map、filter、findなどの配列メソッド
- オブジェクト操作:プロパティアクセス、オプショナルチェーニング、不変更新
- 非同期処理:Promise、async/awaitを使ったAPI通信
- モジュールシステム:import/exportを使ったコード分割
成功のポイントも覚えておきましょう:
- 段階的学習:1つずつ確実に習得する
- 実践重視:実際にコードを書いて理解を深める
- 継続的練習:毎日少しずつでも続ける
- 準備の完了:チェックリストで準備状況を確認
これらの前提知識を身につけることで、React学習がスムーズに進みます。 急がず基礎を固めることが、結果的に最も効率的な学習方法です。
あなたのReact学習が成功し、素晴らしいWebアプリケーションを作成できることを応援しています。 まずは今日から、JavaScriptの基礎固めを始めてみてください!