Search code examples
reactjsdynamic-formsdynamicform

JSReact, Deleting any dynamically added form content other than last item wipes the form


I'm building a form with dynamically added fields and am working on the ability to delete fields if a user changes their mind about one. When deleting the last item added it works as expected, but if I have, for example, 3 dynamically added fields and delete the 2nd one, it will momentarily work and then wipe the whole form clean. Does anyone know why this might be happening?

Codesandbox link here, but I'm including (what I think is) all the relevant code below:

From "form.js":

import React, { useState } from "react";
import CreditInputs from "./CreditInputs";

...


// Create an array that is all current credits except the one being deleted, set credit state to reflect new list
    const handleDeleteCredit = (e) => {
    const updatedCredits = [...creditState];
    updatedCredits.splice(parseInt(e.target.dataset.idx), 1)
    setCreditState(updatedCredits);
}

return (
    <form>            
        <label htmlFor="title">Title</label>   
        <input type="text" name="title" id="title" value={productionState.title} onChange={handleProductionChange} /> 
        <label htmlFor="production_note">Production Note</label> 
        <input type="textarea" name="production_note" id="production_note" value={productionState.production_note} onChange={handleProductionChange} />
        {
            creditState.map((val, idx) => (
                    <CreditInputs
                        key={`credit-${idx}`}
                        idx={idx}
                        creditState={creditState}
                        handleCreditChange={handleCreditChange}
                        // Pass each credit the handleDeleteCredit function
                        handleDeleteCredit={handleDeleteCredit}
                    />
            ))   
        }
        <input type="button" value="Add New Credit" onClick={addCredit}/>       
        <input type="submit" value="Submit" />        
    </form>
)
}

export default Form;

and from "CreditInputs.js":

import React from "react";
import PropTypes from "prop-types";

// Take in the handleDeleteCredit function
    const CreditInputs = ({
        idx,
        creditState,
        handleCreditChange,
        handleDeleteCredit
     }) => {
    const creditId = `name-${idx}`;
    const roleId = `role-${idx}`;
    const bioId = `bio-${idx}`;

    return (
       <div key={`credit-${idx}`}>
       <label htmlFor={creditId}>{`Credit #${idx + 1} Name`}</label>
       
       ...

       {/* Make Delete Button */}
       <button data-idx={idx} onClick={handleDeleteCredit}>Delete Credit</button>
       </div>
     );
     };

     CreditInputs.propTypes = {
       idx: PropTypes.number,
       creditState: PropTypes.array,
       handleCreditChange: PropTypes.func,
       //   Assign handleDeleteCredit a PropType
       handleDeleteCredit: PropTypes.func
     };

     export default CreditInputs;

Any ideas would be much appreciated!


Solution

  • You must call e.preventDefault() at the top of handleDeleteCredit. The problem was default form behavior and the result was the entire page reloading fresh.

     const handleDeleteCredit = (e) => {
        e.preventDefault();
        const updatedCredits = [...creditState];
        updatedCredits.splice(parseInt(e.target.dataset.idx), 1)
        setCreditState(updatedCredits);
    }