CodexBloom - Programming Q&A Platform

React 18: Handling State with useReducer for Dynamic Form Fields and Maintaining Validations

πŸ‘€ Views: 67 πŸ’¬ Answers: 1 πŸ“… Created: 2025-06-12
react usestate usereducer dynamic-forms javascript

I just started working with I'm a bit lost with I'm stuck trying to I've been banging my head against this for hours..... I'm currently building a dynamic form in React 18 where users can add or remove fields for inputting their skills. I'm using `useReducer` to manage the state of the form fields and their validations. However, I'm working with an scenario where the state doesn't seem to update correctly when I remove a field, and the validation messages for other fields also get lost. Here’s a simplified version of my code: ```jsx import React, { useReducer } from 'react'; const initialState = { fields: [], errors: {} }; function reducer(state, action) { switch (action.type) { case 'ADD_FIELD': return { ...state, fields: [...state.fields, ''], errors: { ...state.errors, [`field${state.fields.length}`]: '' } }; case 'REMOVE_FIELD': const newFields = state.fields.filter((_, index) => index !== action.index); const { [action.fieldName]: removedField, ...newErrors } = state.errors; return { ...state, fields: newFields, errors: newErrors }; case 'UPDATE_FIELD': const updatedFields = [...state.fields]; updatedFields[action.index] = action.value; return { ...state, fields: updatedFields }; case 'SET_ERROR': return { ...state, errors: { ...state.errors, [action.fieldName]: action.errorMessage } }; default: return state; } } const DynamicForm = () => { const [state, dispatch] = useReducer(reducer, initialState); const handleAddField = () => { dispatch({ type: 'ADD_FIELD' }); }; const handleRemoveField = (index) => { dispatch({ type: 'REMOVE_FIELD', index, fieldName: `field${index}` }); }; const handleChange = (index, value) => { dispatch({ type: 'UPDATE_FIELD', index, value }); // Example validation logic if (value.length < 3) { dispatch({ type: 'SET_ERROR', fieldName: `field${index}`, errorMessage: 'Input must be at least 3 characters' }); } else { dispatch({ type: 'SET_ERROR', fieldName: `field${index}`, errorMessage: '' }); } }; return ( <form> {state.fields.map((field, index) => ( <div key={index}> <input value={field} onChange={(e) => handleChange(index, e.target.value)} placeholder={`Skill ${index + 1}`} /> {state.errors[`field${index}`] && <span>{state.errors[`field${index}`]}</span>} <button type="button" onClick={() => handleRemoveField(index)}>Remove</button> </div> ))} <button type="button" onClick={handleAddField}>Add Skill</button> </form> ); }; export default DynamicForm; ``` The question arises when I remove a field; the validation messages for the remaining fields are not preserved, causing them to reset or disappear. I'm also getting the following behavior in the console when I try to remove a field: "want to read properties of undefined (reading 'field0')". I suspect this is due to how I'm managing the behavior state, but I'm not sure how to fix it to ensure that the validation messages remain intact. Any suggestions on how to resolve this? My development environment is Windows. What am I doing wrong? This is part of a larger service I'm building. For context: I'm using Javascript on Debian. Any pointers in the right direction? Any feedback is welcome! This is my first time working with Javascript 3.11. How would you solve this? My development environment is Windows 11. Any help would be greatly appreciated! This issue appeared after updating to Javascript 3.10. What would be the recommended way to handle this? For reference, this is a production microservice. What would be the recommended way to handle this?