User_3535
User_3535

Reputation: 862

dynamic form in react how to update nested state field in react.js

My state :

this.state = {
        name: '',
        subCatagory: [{ name: '', price: '', customize: [] }],
    };

my form in react.js :

{this.state.subCatagory.map((subCatagory, idx) => (
                <div className="subCatagory" key={idx}>
                    <input
                        type="text"
                        placeholder={`Enter Dish  #${idx + 1} name`}
                        value={subCatagory.name}
                        onChange={this.handlesubCatagoryNameChange(idx)}
                    />
                    <input
                        type="number"
                        placeholder={`subCatagory #${idx + 1} price`}
                        value={subCatagory.price}
                        onChange={this.handlesubCatagoryPriceChange(idx)}
                    />
                    <button
                        type="button"
                        onClick={this.handleRemovesubCatagory(idx)}
                        className="small"
                    >
                        Delete
                    </button>
                    <button type="button" onClick={this.addNewCust(idx)} className="small">
                        is cust availble?
                    </button>
                    {subCatagory.customize.map((customize, custIdx) => (
                        <div key={custIdx}>
                            <input
                                type="text"
                                placeholder={`subCatagory #${custIdx + 1} price`}
                                value={customize.name}
                                onChange={this.handlesubCatagoryChange(
                                    idx,
                                    'customize',
                                    custIdx
                                )}
                            />
                        </div>
                    ))}
                </div>
            ))}

i want to update every time when a value is updated in input handlesubCatagoryChange and my form is dynamic one ., here i took index of first map and then index of second map but can't able to update the state in react

Upvotes: 0

Views: 1033

Answers (2)

Manoz
Manoz

Reputation: 6617

Change button to use event as well

{this.handlesubCatagoryNameChange.bind(this,idx)}

Then use Object.assign

handlesubCatagoryNameChange(idx,e){
        let subCatagory = Object.assign({}, this.state.subCatagory); //creating copy of object in state
        subCatagory[idx].name = e.target.value
        this.setState({ subCatagory });
    };

Upvotes: 1

TryingToImprove
TryingToImprove

Reputation: 7407

You can update the item in the array with a function like this

handlesubCatagoryNameChange = idx => e => {
    const value = e.target.value;

    this.setState(prevState => ({
        ...prevState,
        subCatagory: subCatagory.map((x, i) => {
            if (i === idx) {
                return {
                    ...x,
                    name: value
                }
            }

            return x
        })
    }))
}

(this is only for the name, you will need the same method for the other fields)

This will keep your subCategory array immutable, and only update the item on the specified index.

For the nested array, you will do the same - something like this (if I understand correctly)

handlesubCatagoryChange  = (otherIdx, propertyPath, innerIdx) => e => {
    const value = e.target.value;

    this.setState(prevState => ({
        ...prevState,
        subCatagory: subCatagory.map((x, i) => {
            if (i === otherIdx) {
                return {
                    ...x,
                    [propertyPath]: x[propertyPath].map((y, j) => {
                        if (j === innerIdx) {
                            return {
                                ...y,
                                name: value
                            }
                        }

                        return y
                    })
                }
            }

            return x
        })
    }))
}

Upvotes: 1

Related Questions