React

ReactのPropsとState

ユーザー操作で変化するデータをstateで管理し、コンポーネント間で共有します。

React入門の講座一覧

01

useStateを使う

useStateはコンポーネントに値を記憶させるHookです。現在値と更新関数を配列分割代入で受け取ります。

カウンターJSX
import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);
  return (
    <>
      <p>現在: {count}</p>
      <button onClick={() => setCount(current => current + 1)}>+1</button>
    </>
  );
}
操作結果OUTPUT
現在: 0
クリック後: 現在: 1

更新関数を呼ぶと、その場の変数が直ちに変わるのではなく、次のレンダーで新しい値が使われます。同じイベント内で前の値を何度も使うときは関数形式を使います。

02

イベント処理

JSXのonClickやonChangeへ関数を渡します。関数を実行した結果ではなく、後で呼ぶ関数そのものを渡す点に注意します。

クリックと入力JSX
function handleClick() {
  console.log('クリックされました');
}

return (
  <>
    <button onClick={handleClick}>確認</button>
    <input onChange={event => console.log(event.target.value)} />
  </>
);

onClick={handleClick}はクリック時に呼びますが、onClick={handleClick()}はレンダー中に実行してしまいます。イベントオブジェクトから入力値を読む場合はevent.target.valueを使います。

03

オブジェクトと配列を更新する

stateの配列やオブジェクトを直接変更せず、新しい配列・オブジェクトを作って更新します。

オブジェクトの更新JSX
import { useState } from 'react';

const [profile, setProfile] = useState({ name: 'Mika', age: 20 });

function birthday() {
  setProfile(current => ({ ...current, age: current.age + 1 }));
}
配列から削除JSX
function removeTodo(id) {
  setTodos(current => current.filter(todo => todo.id !== id));
}

スプレッド構文で元の値をコピーし、変更したい部分だけ置き換えます。直接profile.age++やtodos.push()をすると、Reactが変更を検知できない原因になります。

04

Stateを持ち上げる

複数の子コンポーネントが同じデータを使うときは、共通の親へstateを移し、propsで値と更新関数を渡します。

親がstateを管理するJSX
import { useState } from 'react';

function Input({ value, onChange }) {
  return <input value={value} onChange={event => onChange(event.target.value)} />;
}

function Preview({ value }) { return <p>入力: {value}</p>; }

export default function App() {
  const [text, setText] = useState('');
  return <><Input value={text} onChange={setText} /><Preview value={text} /></>;
}

stateの所有者を一か所に決めると、入力欄とプレビューが同じ値を表示できます。stateをどこへ置くかは、コンポーネント設計で最も重要な判断の一つです。