初級問題(9問)
JSXの書き方
- 以下のHTMLをJSXに変換してください。
<div class="container">
<h1 id="title">Hello World</h1>
<p>Welcome to React</p>
</div>
- JSXでコメントを書く方法を説明し、以下のdiv要素に「これはサンプルコンポーネントです」というコメントを追加してください。
<div>
<p>Sample Component</p>
</div>
- 以下のJSXコードの間違いを修正してください。
<div>
<img src="image.jpg" alt="Sample">
<button disabled={false}>Click me</button>
</div>
関数型コンポーネント
- “Hello, React!”と表示するシンプルな関数コンポーネントを作成してください。

- 以下の関数コンポーネントをアロー関数で書き直してください。
function Welcome() {
return <h1>Welcome!</h1>;
}
- 関数コンポーネント内で複数の要素を返すにはどうすればよいですか?以下のコードを修正してください。
function MultiElements() {
return (
<h1>Title</h1>
<p>Description</p>
);
}
PropsとStateの基本
- 以下のコンポーネントでpropsとしてnameを受け取り、”Hello, [name]!”と表示するように修正してください。
function Greeting() {
return <div>Hello!</div>;
}
- クラスコンポーネントでstateを初期化する正しい方法を選んでください。
// 選択肢A
class Counter extends React.Component {
state = { count: 0 };
}
// 選択肢B
class Counter extends React.Component {
constructor() {
state = { count: 0 };
}
}
// 選択肢C
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
}
- 以下のコンポーネントで、propsとして渡されるitems配列をリスト表示してください。
function ItemList(props) {
return <div>Items will be listed here</div>;
}
中級問題(15問)
JSXの応用
- 以下の条件に基づいてJSXを記述してください。
- isLoggedInがtrueなら”Welcome back!”を表示
- falseなら”Please sign in”を表示
function Greeting({ isLoggedIn }) { // ここにコードを記述 }
- 以下の数値配列をJSXでリスト表示してください。
const numbers = [1, 2, 3, 4, 5];
コンポーネント名はNumberListです。表示はリスト形式(ul / li タグ)で表示してください。
- 以下のオブジェクトのプロパティをJSXで表示してください。
jsx const user = { name: 'John Doe', age: 30, email: 'john@example.com' };
コンポーネント名はUserInfoです。
コンポーネントの構成
- 親コンポーネントから子コンポーネントにtitleとcontentというpropsを渡し、子コンポーネントで表示してください。
<Child title="タイトルです" content="これはコンテンツです" />
- 以下のコンポーネントを2つの小さなコンポーネントに分割してください。
function UserProfile() {
return (
<div className="profile">
<div className="header">
<h1>User Profile</h1>
</div>
<div className="content">
<p>Name: John Doe</p>
<p>Email: john@example.com</p>
</div>
</div>
);
}
- デフォルトpropsを設定してください。nameが渡されない場合は”Guest”と表示されるように。
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
- 子コンポーネントから親コンポーネントの要素を表示するために、children propを使用してください。親コンポーネントには
<p>This will be rendered as children</p>を入れる。
最終的な出力(HTMLイメージ)
<div>
<p>This will be rendered as children</p>
</div>
Propsのバリデーション
- PropTypesを使用して、以下のコンポーネントのpropsに型チェックを追加してください。
- name: string (必須)
- age: number
- isVerified: boolean (デフォルトfalse)
jsx function User({ name, age, isVerified }) { return ( ¨K64K ); }
State管理
- 以下のクラスコンポーネントで、ボタンクリックでcountを増やす機能を追加してください(イベントハンドラは不要、state更新部分のみ)
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
} // ここにメソッドを追加
}
- 前の問題のCounterコンポーネントを関数コンポーネントとuseStateを使って書き直してください。
function Counter() {
const [count, setCount] = useState(0);
return (
// ここに追加
);
}
- 以下のstate更新がなぜ問題なのか説明し、正しい方法で書き直してください。
this.setState({ counter: this.state.counter + 1 });
this.setState({ counter: this.state.counter + 1 });
- オブジェクト型のstateを更新する正しい方法を選んでください。
state = { user: { name: 'John', age: 30 } };
this.setState({ user: { age: 31 } }); // 更新方法A
this.setState({ user: { ...this.state.user, age: 31 } }); // 更新方法B
- 配列型のstateに新しい項目を追加する正しい方法を選んでください。
state = { items: ['apple', 'banana']};
this.state.items.push('orange');
this.setState({ items: this.state.items }); // 方法A
this.setState({ items: [...this.state.items, 'orange'] }); // 方法B
条件付きレンダリング
- 以下のpropsに基づいて条件付きレンダリングを行ってください。
function DataDisplay({ isLoading, error, data }) { // ここにコードを記述 }
- 以下のコンポーネントで、items配列が空の時に「No items found」と表示するように修正してください。
function ItemList({ items }) {
return (
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
コンポーネントの再利用
- 同じレイアウトで異なる内容を表示できるCardコンポーネントを作成してください。titleとchildrenを受け取って表示します。次の要件を満たす
Cardコンポーネントを作成してください。
titleというpropsを受け取り、カードのヘッダーに表示する- コンポーネントの中に書かれた内容(children)をカードの本文として表示する
- 同じレイアウトで異なる内容を表示できるようにする
さらに、この Card コンポーネントを使って以下のようなUIを作成してください。
- 1つ目のカード:タイトル「お知らせ」、本文「メンテナンスのお知らせです」
- 2つ目のカード:タイトル「プロフィール」、本文「名前:山田太郎」
上級問題(6問)
- 高階コンポーネント(HOC)の基本構造を示してください。withLoadingというHOCを作成し、元のコンポーネントにisLoadingプロップを追加するようにします。

- 高階コンポーネント(HOC)は「コンポーネントを受け取って、新しいコンポーネントを返す関数」です。
- 引数に
WrappedComponentを取ります。 - 戻り値として関数コンポーネントを返します。
isLoadingを props から受け取り、条件分岐します。- 読み込み中ならローディング表示、そうでなければ元コンポーネントを表示します。
- 元コンポーネントには
...propsで残りのpropsを渡します。
- 以下のコンポーネントで、prevPropsとprevStateを使用してcomponentDidUpdateを実装し、countが5の倍数になったときにコンソールにログを出力してください。
class Counter extends React.Component {
state = { count: 0 };
increment = () => {
this.setState(prevState => ({ count: prevState.count + 1 }));
};
componentDidUpdate(prevProps, prevState) {
// ここにコードを記述
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.increment}>Increment</button>
</div>
);
}
}
- 複数のstate更新がバッチ処理されることを確認するコードを記述してください。
- Reactはイベントハンドラ内のstate更新をまとめて処理(バッチ処理)します。
setStateは即時に値を変更しません(非同期的に扱われる)。- 同じ値(count)を元に更新すると上書きされます。
- 最新のstateを使いたい場合は「関数形式(prevState)」を使います。
console.logのタイミングにも注意(更新前の値が出る)です。
- 親コンポーネントから子コンポーネントにコールバック関数を渡し、子コンポーネントで実行するパターンを実装してください。
- 親から子へ「関数」をpropsとして渡します
- 子コンポーネント側でその関数を実行します
- 実質的に「子 → 親へのデータ受け渡し」を実現するパターンです。
- props名は慣例的に
onSomething(例: onClick, onSend)とすることが多いです。 - 子では
props.onSend()のように呼び出すだけです
- 動的コンポーネントレンダリングを実装してください。type propに応じて異なるコンポーネントを表示します(例:type=”alert”ならAlertコンポーネント、type=”warning”ならWarningコンポーネント)。
typeというpropsで分岐します。ifやswitchで表示するコンポーネントを切り替えます。- JSX内で条件分岐するのが基本です。
- コンポーネント自体を変数に代入する方法もあります(応用)。
解答例
初級問題解答
- HTMLをJSXに変換
<div className="container">
<h1 id="title">Hello World</h1>
<p>Welcome to React</p>
</div>
- JSXでコメントを書く方法
<div>
{/* これはサンプルコンポーネントです */}
<p>Sample Component</p>
</div>
- JSXコードの間違いを修正
<div>
<img src="image.jpg" alt="Sample" />
<button disabled={false}>Click me</button>
</div>
- “Hello, React!”と表示するシンプルな関数コンポーネント
function HelloReact() {
return <h1>Hello, React!</h1>;
}
- 関数コンポーネントをアロー関数で
const Welcome = () => <h1>Welcome!</h1>;
- 関数コンポーネント内で複数の要素を返す
function MultiElements() {
return (
<>
<h1>Title</h1>
<p>Description</p>
</>
);
}
- propsとしてnameを受け取り、”Hello, [name]!”と表示
function Greeting({ name }) {
return <div>Hello, {name}!</div>;
}
- 選択肢Cが正解(理由は以下)
super(props)を必ず呼ぶ必要があるthis.stateに初期値を設定する- ES6クラスの正式な初期化方法
- propsとして渡されるitems配列をリスト表示
function ItemList({ items }) {
return (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
}
中級問題解答
- 条件によるJSX
- isLoggedInがtrueなら”Welcome back!”を表示
- falseなら”Please sign in”を表示
function Greeting({ isLoggedIn }) {
return isLoggedIn ? <p>Welcome back!</p> : <p>Please sign in</p>;
}
- 数値配列をJSXでリスト表示
function NumberList() {
const numbers = [1, 2, 3, 4, 5];
return (
<ul>
{numbers.map((number) => (
<li key={number.toString()}>{number}</li>
))}
</ul>
);
}
- オブジェクトのプロパティをJSXで表示
function UserInfo() {
const user = { name: 'John Doe', age: 30, email: 'john@example.com' };
return (
<div>
<p>Name: {user.name}</p>
<p>Age: {user.age}</p>
<p>Email: {user.email}</p>
</div>
);
}
- 親コンポーネントから子コンポーネントにtitleとcontentというpropsを渡し、子コンポーネントで表示
// 親コンポーネント
function Parent() {
return <Child title="Welcome" content="Hello World" />;
}
// 子コンポーネント
function Child({ title, content }) {
return (
<div>
<h1>{title}</h1>
<p>{content}</p>
</div>
);
}
- 一つのコンポーネントを2つの小さなコンポーネントに分割
function Header() {
return (
<div className="header">
<h1>User Profile</h1>
</div>
);
}
function Content() {
return (
<div className="content">
<p>Name: John Doe</p>
<p>Email: john@example.com</p>
</div>
);
}
function UserProfile() {
return (
<div className="profile">
<Header />
<Content />
</div>
);
}
- nameが渡されない場合は”Guest”と表示
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
Welcome.defaultProps = {
name: 'Guest'
};
- 子コンポーネントから親コンポーネントの要素を表示するために、children propを使用
function Parent() {
return (
<Child>
<p>This will be rendered as children</p>
</Child>
);
}
function Child({ children }) {
return <div>{children}</div>;
}
- PropTypesを使用して、以下のコンポーネントのpropsに型チェック
import PropTypes from 'prop-types';
function User({ name, age, isVerified }) {
return (
<div>
<h2>{name}</h2>
<p>Age: {age}</p>
{isVerified && <span>Verified</span>}
</div>
);
}
User.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
isVerified: PropTypes.bool
};
User.defaultProps = {
isVerified: false
};
- ボタンクリックでcountを増やす機能を追加
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
increment = () => { this.setState(prevState => ({ count: prevState.count + 1 })); };
}
- Counterコンポーネントを関数コンポーネントとuseState
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
- setStateは非同期なので、連続して呼び出すと正しく更新されない可能性がある。正しい方法は以下の通り。
this.setState(prevState => ({ counter: prevState.counter + 1 }));
this.setState(prevState => ({ counter: prevState.counter + 1 }));
- 更新方法Bが正解
state = { user: { name: 'John', age: 30 } };
this.setState({ user: { age: 31 } }); // 更新方法A
this.setState({ user: { ...this.state.user, age: 31 } }); // 更新方法B
方法Aがダメな理由
- 既存のプロパティを引き継がない
- 意図せずデータが消える
方法Bが良い理由
- 不変性を保っている(元のオブジェクトを変更しない)
- 必要な部分だけ安全に更新できる
- 方法Bが正解
state = { items: ['apple', 'banana']};
this.state.items.push('orange');
this.setState({ items: this.state.items }); // 方法A
this.setState({ items: [...this.state.items, 'orange'] }); // 方法B
方法Aがダメな理由
- Reactではstateを直接変更してはいけない(不変性の破壊)
- 変更検知が正しく行われない可能性がある
- バグや予期しない挙動の原因になる
方法Bが良い理由
- 不変性を保っている
- Reactが差分を正しく検知できる
- 安全で予測可能な動作になる
- propsに基づいて条件付きレンダリング
function DataDisplay({ isLoading, error, data }) {
if (isLoading) return <Spinner />;
if (error) return <div>Error: {error.message}</div>;
return <div>{data}</div>;
}
- items配列が空の時に「No items found」と表示
function ItemList({ items }) {
return items.length === 0 ? (
<p>No items found</p>
) : (
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
- titleとchildrenを受け取って表示
function Card({ title, children }) {
return (
<div className="card">
<div className="card-header">
<h2>{title}</h2>
</div>
<div className="card-body">
{children}
</div>
</div>
);
}
function App() {
return (
<div>
<Card title="お知らせ">
<p>メンテナンスのお知らせです</p>
</Card>
<Card title="プロフィール">
<p>名前:山田太郎</p>
</Card>
</div>
);
}
上級問題解答
- withLoadingというHOCを作成し、元のコンポーネントにisLoadingプロップを追加
function withLoading(Component) {
return function EnhancedComponent({ isLoading, ...props }) {
if (isLoading) return <div>Loading...</div>;
return <Component {...props} />;
};
}
- prevPropsとprevStateを使用してcomponentDidUpdateを実装し、countが5の倍数で表示
componentDidUpdate(prevProps, prevState) {
if (prevState.count % 5 !== 0 && this.state.count % 5 === 0) {
console.log(`Count is now ${this.state.count}, which is a multiple of 5`);
}
}
- 複数のstate更新がバッチ処理されることを確認
class BatchExample extends React.Component {
state = { count: 0 };
increment = () => {
this.setState({ count: this.state.count + 1 });
this.setState({ count: this.state.count + 1 });
this.setState({ count: this.state.count + 1 });
// 最終的にcountは1だけ増える(バッチ処理される)
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.increment}>Increment</button>
</div>
);
}
}
- 親コンポーネントから子コンポーネントにコールバック関数を渡し、子コンポーネントで実行
// 親コンポーネント
function Parent() {
const handleChildClick = (message) => {
console.log(message);
};
return <Child onClick={handleChildClick} />;
}
// 子コンポーネント
function Child({ onClick }) {
return <button onClick={() => onClick('Child was clicked')>Click me</button>;
}
- type propに応じて異なるコンポーネントを表示
function Alert() {
return <div className="alert">Alert!</div>;
}
function Warning() {
return <div className="warning">Warning!</div>;
}
function DynamicComponent({ type }) {
const components = { alert: Alert, warning: Warning };
const Component = components[type] || null;
return Component ? <Component /> : null;
}