こんにちは、デザイナーの早狩です。
Reactを学び始めた時、JavaScriptの新しい書き方に戸惑った経験はありませんか?
jQueryからReactに移行すると、ファイル内に当たり前のように書かれる見慣れないJavaScript記法の多さに驚くことがあります。「Reactの書き方が難しい」と感じる原因は、JavaScriptの記法に慣れていないことがある場合も少なくありません。
この記事では、Reactでよく登場するJavaScript記法を中心に、jQueryに慣れた方向けにポイントを絞ってまとめました。
1. アロー関数
従来の書き方
function greet(name) {
return "Hello, " + name;
}
アロー関数の書き方
const greet = (name) => {
return "Hello, " + name;
};
// さらに短く書くことも可能(最初見たら戸惑う)
// 引数が1つだけの時、()を、処理が「1行の式」だけの時、{} と return を省略できる
const greet = name => "Hello, " + name;
Reactでの使用例
const UserList = () => {
const users = ['田中', '佐藤', '鈴木'];
return (
<ul>
{users.map(user => <li key={user}>{user}</li>)}
</ul>
);
};
2. 分割代入
配列やオブジェクトから値を取り出して変数に代入する便利な構文です。
// オブジェクトの分割代入
const user = { name: 'Alice', age: 25 };
const { name, age } = user; // name = 'Alice', age = 25
// Reactでよく使う例:propsの分割代入
// { name, age, email } のように分割代入することで、props.name と書かずにそのまま変数として使える
const UserProfile = ({ name, age, email }) => {
return <div>{name} ({age})</div>;
// <div>Alice (25)</div>
};
// useStateでの使用例
const [count, setCount] = useState(0); // countには初期値(この場合0)が格納され、setCountにはcountを更新する関数が入ります
setCount(count + 1);
3. スプレッド構文
... を使って配列やオブジェクトを展開する構文です。
// 配列のスプレッド
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
// オブジェクトのスプレッド
const user = { name: 'Alice', age: 25 };
const updatedUser = { ...user, age: 26 }; // { name: 'Alice', age: 26 }
// Reactでよく使う例:propsの渡し方
const MyComponent = () => {
const props = { name: 'Alice', age: 25 };
return <UserProfile {...props} />;
// <UserProfile name="Alice" age={25} /> と書いているのと同じ
};
// 状態の更新
const [state, setState] = useState({ count: 0, name: 'test' });
setState({ ...state, count: state.count + 1 });
4. 条件レンダリング(三項演算子)
条件に応じてJSXを出し分ける際に使用する演算子です。
// 基本的な三項演算子
const condition = true;
const result = condition ? 'Yes' : 'No';
// Reactでよく使う例:条件レンダリング
const UserProfile = ({ user, isLoggedIn }) => {
return (
<div>
{isLoggedIn ? (
<div>
<h2>Welcome, {user.name}</h2>
<p>You are logged in</p>
</div>
) : (
<div>
<h2>Please log in</h2>
<button>Login</button>
</div>
)}
</div>
);
};
// インライン条件レンダリング
const Button = ({ loading, children }) => (
<button disabled={loading}>
{loading ? 'Loading...' : children}
</button>
);
5. オプショナルチェーン
?. を使ってnullやundefinedの可能性があるプロパティに安全にアクセスする構文です。
// 従来の書き方
if (main) {
main.querySelectorAll(".profile");
}
// オプショナルチェーンを使った書き方
document.getElementById("main")?.querySelectorAll(".profile");
// id="main" の要素が存在する場合だけ.profile 要素を取得します。
// 無いときは処理を中断し、エラーを出さずに undefined を返す(処理が止まらずに済む)
// Reactでよく使う例
const UserAvatar = ({ user }) => {
return (
<img
src={user?.profile?.avatar?.url || '/default-avatar.png'}
alt={user?.name || 'User'}
/>
);
};
// 配列要素へのアクセス
const firstItem = items?.[0];
// items が存在する場合のみ、先頭の要素を取得する
// items が null / undefined の場合は undefined を返す
6. Null合体演算子(??)
nullまたはundefinedの場合のみデフォルト値を返す演算子です。||演算子とは異なり、0、''、falseは有効な値として扱われます。
// || 演算子と比較すると分かりやすいです
const count = 0;
const display1 = count || 'No data'; // display1 = 'No data' (0はfalsyなので)
// ?? 演算子の利点
const display2 = count ?? 'No data'; // display2 = 0 (nullでもundefinedでもないので)
// Reactでよく使う例
const UserProfile = ({ user }) => {
return (
<div>
<h2>{user?.name ?? 'Anonymous'}</h2>
<p>Age: {user?.age ?? 'Unknown'}</p>
<p>Score: {user?.score ?? 0}</p> {/* scoreが0でも表示される */}
</div>
);
};
7. Null合体代入(??=)
左辺がnullまたはundefinedの場合のみ右辺の値を代入する演算子です。
// 基本的な使い方
let config = {};
config.theme ??= 'light'; // config.themeがnull/undefinedの場合のみ'light'を代入
console.log(config.theme); // 'light' ※上記のNull合体演算子?? では代入されないので、元の config.theme は undefined のまま
config.theme ??= 'dark'; // 既に値があるので代入されない
console.log(config.theme); // 'light' (変わらない)
// Reactでよく使う例:設定の初期化
const useSettings = () => {
const [settings, setSettings] = useState(() => {
const saved = localStorage.getItem('settings');
const parsed = saved ? JSON.parse(saved) : {};
// デフォルト値の設定
parsed.notifications ??= true;
parsed.theme ??= 'light';
parsed.language ??= 'en';
parsed.autoSave ??= false;
return parsed;
});
return [settings, setSettings];
};
8. 論理OR代入(||=)
??=と似ていますが、
左辺がfalsy(false, 0, ''(空文字), null, undefined, NaN)の場合のみ右辺の値を代入する演算子です。
// 基本的な使い方
let message = '';
message ||= 'Default message'; // messageが空文字(falsy)なので代入される
console.log(message); // 'Default message'
let count = 0;
count ||= 10; // countが0(falsy)なので代入される
console.log(count); // 10
let name = 'Alice';
name ||= 'Guest'; // nameは既に値があるので代入されない
console.log(name); // 'Alice'
// Reactでよく使う例:フォールバック値の設定
const UserProfile = ({ user }) => {
// プロフィール情報にフォールバック値を設定
const profile = { ...user.profile };
profile.displayName ||= user.name || 'Anonymous';
profile.bio ||= 'No bio available';
profile.avatar ||= '/default-avatar.png';
return (
<div>
<img src={profile.avatar} alt={profile.displayName} />
<h2>{profile.displayName}</h2>
<p>{profile.bio}</p>
</div>
);
};
// ?? との使い分け
let value1 = 0;
value1 ||= 'default'; // 0はfalsyなので'default'が代入される
let value2 = 0;
value2 ??= 'default'; // 0はnull/undefinedではないので代入されない
9. 論理AND代入(&&=)
左辺がtruthyの場合のみ右辺の値を代入する演算子です。
// 基本的な使い方
let user = { name: 'Alice', isActive: true };
user.isActive &&= false; // isActiveがtruthyなのでfalseが代入される
console.log(user.isActive); // false
let score = 0;
score &&= 100; // scoreが0(falsy)なので代入されない
console.log(score); // 0
// Reactでよく使う例:条件付きデータ変換
const processUserData = (userData) => {
// 名前が存在する場合のみトリム処理を行う
userData.firstName &&= userData.firstName.trim();
userData.lastName &&= userData.lastName.trim();
// プロフィール画像がある場合のみリサイズ処理を行う
userData.avatar &&= resizeImage(userData.avatar);
// 設定が存在する場合のみマージする
userData.settings &&= { ...defaultSettings, ...userData.settings };
return userData;
};
// 他の代入演算子との使い分け
let config = { theme: 'dark' };
config.theme ??= 'light'; // null/undefinedの場合のみ代入
config.theme ||= 'light'; // falsy(false, 0, ''(空文字), null, undefined, NaN)の場合のみ代入
config.theme &&= 'system'; // truthyの場合のみ代入('dark' → 'system')
10. モジュール(import / export)
ES6 のモジュールは、
コードをファイル単位で分割し、必要なものだけを読み込んで使い回す仕組みです。
React では
- コンポーネント
- utility 関数
- API 処理
などを役割ごとに分離するため、ほぼ必須の知識になります。
エクスポート側(utils.js)
・ 名前付きエクスポート(複数OK)
// utils.js
// 名前を指定して外に出す(複数定義できる)
export const formatDate = (date) => {
return date.toLocaleDateString();
};
export const calculateAge = (birthDate) => {
return new Date().getFullYear() - birthDate.getFullYear();
};
・ デフォルトエクスポート(1つだけ)
// utils.js
// このファイルから「1つだけ」export できる
const apiClient = {
get: (url) => fetch(url),
post: (url, data) =>
fetch(url, { method: 'POST', body: JSON.stringify(data) })
};
export default apiClient;
インポート側(UserProfile.js)
・ デフォルトインポート
// default export を {} なしで受け取る
import apiClient from '../utils';
・ 名前付きインポート
// 名前付き export を {} で指定して受け取る
import { formatDate, calculateAge } from '../utils';
他のインポート方法
まとめてインポート(名前空間を作る)
// 名前付きエクスポートを1つのオブジェクトとしてまとめて受け取る
import * as utils from '../utils';
utils.formatDate(date);
utils.calculateAge(date);
エイリアス(名前を変えてインポート)
// import 時に別名を付ける
import { formatDate as format } from '../utils';
format(date);
まとめ
React(tsx)で頻出するJavaScript記法は数が多く、実際のコードでは複数の記法が組み合わされて使われることがほとんどかと思います。
本記事では主に基本構文を取り上げましたが、次回は非同期処理(async/await、Promise)やテンプレートリテラル、オブジェクトの省略記法などを取り上げる予定です。jQuery的な考え方に慣れている方が、Reactのコードを読み解く際の助けになれば幸いです。
KIYOラーニング株式会社について
当社のビジョンは『世界一「学びやすく、分かりやすく、続けやすい」学習手段を提供する』ことです。革新的な教育サービスを作り成長させていく事で、オンライン教育分野でナンバーワンの存在となり、世界に展開していくことを目指しています。
プロダクト
- スタディング:「学びやすく・わかりやすく・続けやすい」オンライン資格対策講座
- スタディングキャリア:資格取得者の仕事探しやキャリア形成を支援する転職サービス
- AirCourse:受け放題の動画研修がついたeラーニングシステム(LMS)
KIYOラーニング株式会社では一緒に働く仲間を募集しています