React) custom Hook - useInputs
import {useReducer} from 'react';
function reducer(state, action){
return{
...state,
[action.name] : action.value
};
}
export default function useInputs(initialForm){
const [state,dispatch] = useReducer(reducer, initialForm);
const onChange = e => {
dispatch(e.target);
};
return [state, onChange];
}
### The Reducer Function
```javascript
function reducer(state, action){
return {
...state,
[action.name]: action.value
};
}
```
- **Purpose**: The reducer function updates the state based on the action dispatched. The action is expected to contain properties that correspond to form inputs.
- **Parameters**:
- `state`: The current state of the inputs.
- `action`: An object that represents the dispatched action. It's expected to contain the `name` and `value` of the form input that triggered the change.
- **Behavior**: The function spreads the existing state to maintain previous state values and then dynamically updates the property defined by `action.name` with `action.value`. This approach ensures that only the field that has changed is updated, preserving other field values in the state.
### The `useInputs` Custom Hook
```javascript
export default function useInputs(initialForm){
const [state, dispatch] = useReducer(reducer, initialForm);
const onChange = e => {
dispatch(e.target);
};
return [state, onChange];
}
```
- **Parameters**:
- `initialForm`: An object representing the initial state of the form. This would typically contain keys corresponding to form fields and initial values for those fields.
- **State Management**:
- `useReducer`: This hook is used to handle state operations more suited to complex state logic. It accepts the `reducer` function and the `initialForm` as arguments. The state (`state`) and dispatch method (`dispatch`) are destructured from its return value.
- **Event Handler (`onChange`)**:
- `onChange`: A function designed to handle input changes. It takes an event object (`e`), and dispatches the event's target (which contains the input's `name` and `value`).
- **Behavior**: When a user types into an input, this function dispatches an action with the input element itself as the action. This is somewhat unconventional because typically only essential data (like `{ name, value }`) is dispatched rather than the whole DOM element. It's efficient here since `reducer` directly uses the `name` and `value` properties of the dispatched object.
- **Return Value**:
- The hook returns an array containing the `state` and the `onChange` handler. This structure allows the hook to be easily integrated into components, mirroring the familiar `[value, setter]` pattern used with `useState`.
### Usage Example in a Component
Here's a brief example showing how this hook could be utilized within a React component:
```jsx
import useInputs from './useInputs';
const MyForm = () => {
const [inputs, setInputs] = useInputs({ name: '', age: '' });
return (
<form>
<input name="name" value={inputs.name} onChange={setInputs} />
<input name="age" value={inputs.age} onChange={setInputs} />
<button type="submit">Submit</button>
</form>
);
};
```
### Conclusion
Your `useInputs` hook abstracts away the complexity of form state management, making it highly reusable across different components. It handles each form field's state changes efficiently using `useReducer`, which is particularly useful in forms with a large number of fields or complex state interactions. This hook showcases a powerful way to use `useReducer` for handling form states and can be further extended or modified to include additional functionalities like form validation.