React コンポーネント開発:制御コンポーネントと非制御コンポーネントを使い分ける
React 制御コンポーネントと非制御コンポーネント
制御コンポーネント
制御コンポーネント は、コンポーネント自身の状態 (this.state
) で入力値を管理します。親コンポーネントから props
を介して値を受け取り、その値を更新することで、子コンポーネントのレンダリングを制御します。
特徴
- 状態を
this.state
で管理 - 親コンポーネントから
props
で値を受け取る - 親コンポーネントから
props
を介して値を更新することでレンダリングを制御 - フォーム要素など、動的な入力値を扱うコンポーネントに適している
例
class ControlledInput extends React.Component {
constructor(props) {
super(props);
this.state = {
value: this.props.initialValue,
};
}
handleChange = (event) => {
this.setState({ value: event.target.value });
};
render() {
return (
<input
type="text"
value={this.state.value}
onChange={this.handleChange}
/>
);
}
}
この例では、ControlledInput
コンポーネントは initialValue
という props
を受け取り、その値を this.state.value
に格納します。ユーザーが入力値を変更すると、handleChange
関数が呼び出され、this.state.value
が更新されます。そして、value
プロパティが更新されることで、コンポーネントが再レンダリングされます。
非制御コンポーネント
非制御コンポーネント は、DOM 自身で入力値を管理します。コンポーネントは props
を介して初期値を設定できますが、その後は DOM の値を参照することで入力値を取得します。
- 状態を DOM 自身で管理
- DOM の値を参照することで入力値を取得
- シンプルなコンポーネントに適している
const UncontrolledInput = ({ initialValue }) => {
const [value, setValue] = React.useState(initialValue);
const handleChange = (event) => {
setValue(event.target.value);
};
return (
<input
type="text"
defaultValue={initialValue}
onChange={handleChange}
/>
);
};
この例では、UncontrolledInput
コンポーネントは initialValue
という props
を受け取り、その値を defaultValue
プロパティとして設定します。ユーザーが入力値を変更すると、handleChange
関数が呼び出され、value
変数が更新されます。
使い分け
制御コンポーネントと非制御コンポーネントは、それぞれ異なる状況で使い分けられます。
制御コンポーネント は、以下の状況で適しています。
- 入力値の検証やバリデーションを行うコンポーネント
- 親コンポーネントから子コンポーネントへの値の受け渡しが必要なコンポーネント
React コンポーネントには、状態の管理方法によって 制御コンポーネント と 非制御コンポーネント の 2 種類があります。それぞれの特徴と使い分けを理解することで、状況に応じて適切なコンポーネントを選択することができます。
制御コンポーネント
class ControlledInput extends React.Component {
constructor(props) {
super(props);
this.state = {
value: this.props.initialValue,
};
}
handleChange = (event) => {
this.setState({ value: event.target.value });
};
render() {
return (
<input
type="text"
value={this.state.value}
onChange={this.handleChange}
/>
);
}
}
const App = () => {
const [count, setCount] = React.useState(0);
const handleCountChange = () => {
setCount(count + 1);
};
return (
<div>
<ControlledInput initialValue={count} />
<button onClick={handleCountChange}>Count Up</button>
</div>
);
};
App
コンポーネントでは、ControlledInput
コンポーネントを count
という変数の値でレンダリングしています。count
変数が更新されると、ControlledInput
コンポーネントが再レンダリングされ、新しい値が表示されます。
非制御コンポーネント
const UncontrolledInput = ({ initialValue }) => {
const [value, setValue] = React.useState(initialValue);
const handleChange = (event) => {
setValue(event.target.value);
};
return (
<input
type="text"
defaultValue={initialValue}
onChange={handleChange}
/>
);
};
const App = () => {
const [count, setCount] = React.useState(0);
const handleCountChange = () => {
setCount(count + 1);
};
return (
<div>
<UncontrolledInput initialValue={count} />
<button onClick={handleCountChange}>Count Up</button>
</div>
);
};
上記のコード例は、制御コンポーネントと非制御コンポーネントの基本的な動作を示しています。それぞれのコンポーネントの特徴と使い分けを理解することで、状況に応じて適切なコンポーネントを選択することができます。
制御コンポーネントと非制御コンポーネントのその他の方法
制御コンポーネント
- React.createRef を使用して、DOM 要素への参照を取得し、その参照を使用して値を更新することができます。
- React.useState フックを使用して、コンポーネントの状態を管理することができます。
非制御コンポーネント
- カスタムフック を使用して、状態の管理と値の更新をカプセル化することができます。
- シンプルなコンポーネントの場合は、非制御コンポーネント を使用するのがおすすめです。
reactjs react-component