Home > database >  React add new input have same value for all items
React add new input have same value for all items

Time:12-22

I have a input form that can dynamically add new inputs like this:

const [inputVariationFields, setInputVariationFields] = useState<AddProductVariationForm[]>([])
const addVariationFields = () => {
    let newfield = AddProductVariationInitialValue

    setInputVariationFields([...inputVariationFields, newfield])
}

let removeVariationFields = (i: number) => {
    let newFormValues = [...inputVariationFields];
    newFormValues.splice(i, 1);
    setInputVariationFields(newFormValues)
}

{
    inputVariationFields.map((element, index) => (
        <div className="my-3 p-3 border border-gray-lighter rounded" key={index}>
            <div className='w-full'>
                <label htmlFor={'name_1_'   index.toString} className='font'>
                    Variation Name 1
                    <BaseInput
                        key={'name_1_'   index.toString}
                        id={index.toString()}
                        name={'name_1_'   index.toString}
                        type='text'
                        value={element.name_1 || ''}
                        onChange={(e) => {
                            let newFormValues = [...inputVariationFields];
                            console.log(newFormValues)
                            newFormValues[index].name_1 = e.target.value;
                            setInputVariationFields(newFormValues);
                        }}
                        value={element.name_1 || ''}
                        placeholder='Product variation name 1'
                    />
                </label>
            </div>

            ...

            {
                index ?
                    <div className='mt-5 mb-2'>
                        <OutlinedButton key={index} onClick={() => removeVariationFields(index)}>
                            Remove
                        </OutlinedButton>
                    </div>
                    : null
            }
        </div>
    ))
}
<div className="my-3">
    <PrimaryButton
        type='button'
        onClick={() => addVariationFields()}
    >
        Add variation
    </PrimaryButton>
</div>

But when I add the new variation field, and insert the value of name_1, it change the value of the new variation name_1 field as well. How to insert name_1 with different value of each variation?

Note: I'm using typescript and the InputVariationField is an array of object that have keys like name_1 and more.

CodePudding user response:

I mean, the init value of inputVariationFields like:

const [inputVariationFields, setInputVariationFields] = useState([{ name_1: "" }]);

In addVariationFields function, you must init a object with name_1 is empty, like:

const addVariationFields = () => {
    const newfield = { name_1: "" };
    setInputVariationFields([...inputVariationFields, newfield]);
  };

Error in your onChange handle and value of input. I make a new function to handle onChange of input.

const onChangeInput = (e, index) => {
    e.preventDefault();
    const newArray = inputVariationFields.map((ele, i) => {
      if (index === i) {
        ele.name_1 = e.target.value;
      }
      return ele;
    });
    setInputVariationFields(newArray);
}

{
    inputVariationFields.map((element, index) => (
        <div className="my-3 p-3 border border-gray-lighter rounded" key={index}>
            <div className='w-full'>
                <label htmlFor={'name_1_'   index.toString} className='font'>
                    Variation Name {index   1}
                    <BaseInput
                        key={'name_1_'   index.toString}
                        id={index.toString()}
                        name={'name_1_'   index.toString}
                        type='text'
                        onChange={(e) => onChangeInput(e, index)}
                        value={element.name_1 || ""}
                        placeholder={`Product variation name `   (index   1)}
                    />
                </label>
            </div>

            {
                index ?
                    <div className='mt-5 mb-2'>
                        <OutlinedButton key={index} onClick={() => removeVariationFields(index)}>
                            Remove
                        </OutlinedButton>
                    </div>
                    : null
            }
        </div>
    ))
}

Check out:

https://codesandbox.io/s/friendly-forest-38esp3?file=/src/Test.js

Hope that it helps

CodePudding user response:

You are spreading the same object ("newField") into inputVariationFields every time you call addVariationFields. This causes every element in the array to be a pointer to the same object. So everytime you change a property of one element it changes the same property of every other element in the array.

To solve this mistake add a new object when calling addVariationFields instead of the same each time. You can do this by creating a new object with {...AddProductVariationInitialValue} This new object will have the same properties as .AddProductVariationInitialValue.

const addVariationFields = () => {
    let newfield = {...AddProductVariationInitialValue}

    setInputVariationFields([...inputVariationFields, newfield])
}

I hope this solves your problem

  • Related