React演習問題(JSX・コンポーネント・Props・State)

2025-08-08

初級問題(9問)

JSXの書き方

  1. 以下のHTMLをJSXに変換してください:
<div class="container">
  <h1 id="title">Hello World</h1>
  <p>Welcome to React</p>
</div>
  1. JSXでコメントを書く方法を説明し、以下のdiv要素に「これはサンプルコンポーネントです」というコメントを追加してください:
<div>
  <p>Sample Component</p>
</div>
  1. 以下のJSXコードの間違いを修正してください:
<div>
  <img src="image.jpg" alt="Sample">
  <button disabled={false}>Click me</button>
</div>

関数型コンポーネント

  1. “Hello, React!”と表示するシンプルな関数コンポーネントを作成してください。
  2. 以下の関数コンポーネントをアロー関数で書き直してください:
function Welcome() {
  return <h1>Welcome!</h1>;
}
  1. 関数コンポーネント内で複数の要素を返すにはどうすればよいですか?以下のコードを修正してください:
function MultiElements() {
  return (
    <h1>Title</h1>
    <p>Description</p>
  );
}

PropsとStateの基本

  1. 以下のコンポーネントでpropsとしてnameを受け取り、”Hello, [name]!”と表示するように修正してください:
   function Greeting() {
     return <div>Hello!</div>;
   }
  1. クラスコンポーネントで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 };
     }
   }
  1. 以下のコンポーネントで、propsとして渡されるitems配列をリスト表示してください:
   function ItemList(props) {
     return <div>Items will be listed here</div>;
   }

中級問題(15問)

JSXの応用

  1. 以下の条件に基づいてJSXを記述してください:

  • isLoggedInがtrueなら”Welcome back!”を表示
  • falseなら”Please sign in”を表示

function Greeting({ isLoggedIn }) { // ここにコードを記述 }
  1. 以下の数値配列をJSXでリスト表示してください:
const numbers = [1, 2, 3, 4, 5];
  1. 以下のオブジェクトのプロパティをJSXで表示してください:
jsx const user = { name: 'John Doe', age: 30, email: 'john@example.com' };

コンポーネントの構成

  1. 親コンポーネントから子コンポーネントにtitleとcontentというpropsを渡し、子コンポーネントで表示してください。
  1. 以下のコンポーネントを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>
  );
}
  1. デフォルトpropsを設定してください。nameが渡されない場合は”Guest”と表示されるように。
function Welcome(props) { 
  return <h1>Hello, {props.name}</h1>; 
}
  1. 子コンポーネントから親コンポーネントの要素を表示するために、children propを使用してください。

Propsのバリデーション

  1. PropTypesを使用して、以下のコンポーネントのpropsに型チェックを追加してください:
  • name: string (必須)
  • age: number
  • isVerified: boolean (デフォルトfalse)
  • jsx function User({ name, age, isVerified }) { return ( ¨K64K ); }

State管理

  1. 以下のクラスコンポーネントで、ボタンクリックでcountを増やす機能を追加してください(イベントハンドラは不要、state更新部分のみ)
class Counter extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; } // ここにメソッドを追加 }
  1. 前の問題のCounterコンポーネントを関数コンポーネントとuseStateを使って書き直してください。
  1. 以下のstate更新がなぜ問題なのか説明し、正しい方法で書き直してください:
this.setState({ counter: this.state.counter + 1 }); this.setState({ counter: this.state.counter + 1 });
  1. オブジェクト型のstateを更新する正しい方法を選んでください:
state = { user: { name: 'John', age: 30 } }; // 更新方法A this.setState({ user: { age: 31 } }); // 更新方法B this.setState({ user: { ...this.state.user, age: 31 } });
  1. 配列型のstateに新しい項目を追加する正しい方法を選んでください:
state = { items: ['apple', 'banana'] }; // 方法A this.state.items.push('orange'); this.setState({ items: this.state.items }); // 方法B this.setState({ items: [...this.state.items, 'orange'] });

条件付きレンダリング

  1. 以下のpropsに基づいて条件付きレンダリングを行ってください:

  • isLoadingがtrueならローディングスピナーを表示
  • errorがあればエラーメッセージを表示
  • それ以外ならdataを表示

function DataDisplay({ isLoading, error, data }) { // ここにコードを記述 }
  1. 以下のコンポーネントで、items配列が空の時に「No items found」と表示するように修正してください:
function ItemList({ items }) { 
  return (
    <ul>
      {items.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  ); 
}

コンポーネントの再利用

  1. 同じレイアウトで異なる内容を表示できるCardコンポーネントを作成してください。titleとchildrenを受け取って表示します。

上級問題(6問)

  1. 高階コンポーネント(HOC)の基本構造を示してください。withLoadingというHOCを作成し、元のコンポーネントにisLoadingプロップを追加するようにします。
  1. 以下のコンポーネントで、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>
    );
  }
}
  1. 複数のstate更新がバッチ処理されることを確認するコードを記述してください。
  1. 親コンポーネントから子コンポーネントにコールバック関数を渡し、子コンポーネントで実行するパターンを実装してください。
  1. 動的コンポーネントレンダリングを実装してください。type propに応じて異なるコンポーネントを表示します(例:type=”alert”ならAlertコンポーネント、type=”warning”ならWarningコンポーネント)。

解答例

初級問題解答

  1. HTMLをJSXに変換
<div className="container"> 
  <h1 id="title">Hello World</h1> 
  <p>Welcome to React</p> 
</div>
  1. JSXでコメントを書く方法
<div>
  {/* これはサンプルコンポーネントです */}
  <p>Sample Component</p>
</div>
  1. JSXコードの間違いを修正
<div> 
  <img src="image.jpg" alt="Sample" /> 
  <button disabled={false}>Click me</button> 
</div>
  1. “Hello, React!”と表示するシンプルな関数コンポーネント
function HelloReact() {
  return <h1>Hello, React!</h1>;
}
  1. 関数コンポーネントをアロー関数で
const Welcome = () => <h1>Welcome!</h1>;
  1. 関数コンポーネント内で複数の要素を返す

function MultiElements() {
  return (
    <>
      <h1>Title</h1>
      <p>Description</p>
    </>
  );
}
  1. propsとしてnameを受け取り、”Hello, [name]!”と表示
function Greeting({ name }) { return <div>Hello, {name}!</div>; }
  1. 選択肢Cが正解
  1. propsとして渡されるitems配列をリスト表示
function ItemList({ items }) {
  return (
    <ul>
      {items.map((item, index) => (
        <li key={index}>{item}</li>
      ))}
    </ul>
  );
}

中級問題解答

  1. 条件によるJSX
  • isLoggedInがtrueなら”Welcome back!”を表示
  • falseなら”Please sign in”を表示
function Greeting({ isLoggedIn }) { 
  return isLoggedIn ? <p>Welcome back!</p> : <p>Please sign in</p>; 
}
  1. 数値配列をJSXでリスト表示
function NumberList() {
  const numbers = [1, 2, 3, 4, 5];
  return (
    <ul>
      {numbers.map((number) => (
        <li key={number.toString()}>{number}</li>
      ))}
    </ul>
  );
}
  1. オブジェクトのプロパティを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>
  );
}
  1. 親コンポーネントから子コンポーネントに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>
  );
}
  1. 一つのコンポーネントを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>
  );
}
  1. nameが渡されない場合は”Guest”と表示
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

Welcome.defaultProps = {
  name: 'Guest'
};
  1. 子コンポーネントから親コンポーネントの要素を表示するために、children propを使用
function Parent() {
  return (
    <Child>
      <p>This will be rendered as children</p>
    </Child>
  );
}

function Child({ children }) {
  return <div>{children}</div>;
}
  1. 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
};
  1. ボタンクリックでcountを増やす機能を追加
increment = () => { this.setState(prevState => ({ count: prevState.count + 1 })); };
  1. Counterコンポーネントを関数コンポーネントとuseState
function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}
  1. setStateは非同期なので、連続して呼び出すと正しく更新されない可能性がある。正しい方法:
this.setState(prevState => ({ counter: prevState.counter + 1 }));
this.setState(prevState => ({ counter: prevState.counter + 1 }));
  1. 更新方法Bが正解
  2. 方法Bが正解
  1. propsに基づいて条件付きレンダリング
function DataDisplay({ isLoading, error, data }) {
  if (isLoading) return <Spinner />;
  if (error) return <div>Error: {error.message}</div>;
  return <div>{data}</div>;
}
  1. 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>
  );
}
  1. 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>
  );
}

上級問題解答

  1. withLoadingというHOCを作成し、元のコンポーネントにisLoadingプロップを追加
function withLoading(Component) {
  return function EnhancedComponent({ isLoading, ...props }) {
    if (isLoading) return <div>Loading...</div>;
    return <Component {...props} />;
  };
}
  1. 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`);
  }
}
  1. 複数の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>
    );
  }
}
  1. 親コンポーネントから子コンポーネントにコールバック関数を渡し、子コンポーネントで実行
// 親コンポーネント
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>;
}
  1. 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;
}