React コンポーネントの入力管理
Reactにおける制御されたコンポーネントと非制御されたコンポーネント
Reactでは、コンポーネントの入力値を管理する方法として、大きく分けて2つのアプローチがあります。それが制御されたコンポーネントと非制御されたコンポーネントです。
制御されたコンポーネント (Controlled Components)
-
例
import React, { useState } from 'react'; function ControlledInput() { const [value, setValue] = useState(''); const handleChange = (event) => { setValue(event.target.value); }; return ( <input type="text" value={value} onChange={handl eChange} /> ); }
-
特徴
- コンポーネントの内部状態を使って入力値を管理します。
- コンポーネントのレンダリング時に、入力値を直接指定します。
- 入力値が変更されるたびに、コンポーネントの内部状態が更新され、再レンダリングされます。
-
import React from 'react'; function UncontrolledInput() { const handleSubmit = (event) => { event.preventDefault(); const value = event.target.elements.inputElement.value; console.log(value); }; return ( <form onSubmit={handleSubmit}> <input type="text" name="inputElement" /> <button type="submit">Submit</button> </form> ); }
-
- コンポーネントの内部状態ではなく、DOM要素の
value
属性を使って入力値を管理します。 - 入力値が変更されたときに、コンポーネントの内部状態は更新されません。
- コンポーネントの内部状態ではなく、DOM要素の
どちらを使うべきか
-
非制御されたコンポーネント
- シンプルな入力フォームで、状態管理が不要な場合。
- フォームの送信時に、DOM要素の値を取得するだけで十分な場合。
-
- 入力のバリデーションやフォーマッティングが必要な場合。
- フォームの送信前にデータの整合性を確認したい場合。
- 入力の状態を他のコンポーネントと共有したい場合。
制御されたコンポーネントと非制御されたコンポーネントのコード解説
制御されたコンポーネントのコード解説
import React, { useState } from 'react';
function ControlledInput() {
const [value, setValue] = useState('');
const handleChange = (event) => {
setValue(event.target.value);
};
return (
<input type="text" value={value} onChange={handleChange} />
);
}
- input要素
value
プロパティにvalue
状態をバインドします。onChange
プロパティにhandleChange
関数を設定します。
- handleChange関数
入力値が変更されたときに呼び出されます。event.target.value
を取得して、setValue
関数を使ってvalue
の状態を更新します。
- u seStateフック
コンポーネントの内部状態value
を初期化します。
import React from 'react';
function UncontrolledInput() {
const handleSubmit = (event) => {
event.preventDefault();
const value = event.target.elements.inputElement.value;
console.log(value);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" name="inputElement" />
<button type="submit">Submit</button>
</form>
);
}
- input要素
- form要素
- handleSubmit関数
フォームが送信されたときに呼び出されます。event.preventDefault()
でデフォルトのフォーム送信動作を防止します。event.target.elements.inputElement.value
で入力値を取得します。
コードの違いとポイント
-
- DOM要素の
value
属性を使って入力値を管理します。 - コンポーネントの内部状態は更新されません。
- フォームの送信時に、入力値を取得するだけです。
- DOM要素の
-
- フォームの送信前に、入力値のバリデーションやフォーマッティングが可能です。
カスタムフックの使用
- 例
import { useState } from 'react'; function useControlledInput(initialValue) { const [value, setValue] = useState(initialValue); const handleChange = (event) => { setValue(event.target.value); }; return [value, handleChang e]; } function MyComponent() { const [value, handleChange] = useControlledInput(''); return ( <input type="text" value={value} onChange={handleChange} /> ); }
- 利点
- コードの再利用性が高まる。
- 複雑な入力管理ロジックをカプセル化できる。
ReduxまたはContext APIの使用
- 例
import React, { useContext } from 'react'; import { useSelector, useDispatch } from 'react-redux'; // Redux store const store = createStore(/* ... */); // Redux action const changeInputValue = (value) => ({ type: 'CHANGE_INPUT_VALUE', value }); // Redux reducer const reducer = (state = '', action) => { switch (action.type) { case 'CHANGE_INPUT_VALUE': return action.value; default: return state; } }; // Context API const InputContext = createContext(); function InputProvider({ children }) { const dispatch = useDispatch(); const value = useSelector((state) => state.inputValue); const handleChange = (event) => { dispatch(changeInputValue(event.target.value)); }; return ( <InputContext.Provider value={{ value, handleChange }}> {children} </InputContext.Provider> ); } function MyComponent() { const { value, handleChange } = useContext(InputContext); return ( <input type="text" value={value} onChange={handleChange} /> ); }
- 利点
- アプリケーション全体で状態を管理できる。
- コンポーネント間の状態共有が容易になる。
Formライブラリの使用
- 例
import React, { useState } from 'react'; import { useForm } from 'react-hook-form'; function MyComponent() { const { register, handleSubmit, errors } = useForm(); const onSubmit = (data) => { console.log(data); }; return ( <form onSubmit={handleSubmit(onSubmit)}> <inp ut type="text" name="input" ref={register({ required: true })} /> {errors.input && <p>Input is required</p>} <button type="submit">Submit</button> </form> ); }
- 利点
- フォームの入力管理やバリデーションを簡素化できる。
- 多くの機能が提供されている。
reactjs react-component