How to attach an onChange event to the currently selected input that gets value from an array of objects? -ReactJS

How to attach an onChange event to the currently selected input that gets value from an array of objects? -ReactJS
0

#1

This is my array of objects:

 this.state = {
      recipes: [
        {
          name: "test123",
          products: ["313", "dasd", "dasfg"]
        },
        {
          name: "test",
          products: ["product", "product 2", "product 2", "product 3"]
        }
      ]

This is how I render the products:

let id = this.props.currentRecipe; // the Id is just to select the object that I want to render
let recipes = this.props.recipes[id];


{recipes.products.map((product, id) => {
 return (
      <FormControl
           key={product + '_' + id}
            type="text"
            value={product}
            onChange={this.editProduct.bind(this, id)}
            placeholder={"Product " + (id + 1)}
      />
  );
})}

This is my child function where I call my parent function:

 editProduct(i, event) {
    this.props.handleEditProduct(i, event);
  }

What my parent function should look like?

  handleEditProduct(i, event) {
   .... ?
  }

#2

It’s difficult to help you without a full view of your app. For instance, why are you selecting the object you want to render with an index? Why are you calling this.props.handleEditProduct in another function? You may have good reasons for your choices, but with what you’ve given here, it’s a bit confusing. Could you post your whole project, either as a Codepen or just your repository?


#3

Here we go. I am calling that function from my child component but I’m not sure if this is the right way. + my code is really messy but I am new to React and I will refactor it later.


#4

It looks good. I think you’re almost there.

On line 78, you’re binding an index to one of your functions. I would also do this for your edit function. Instead of passing your EditRecipe component all of the recipes, just get the one recipe it needs and pass that. As you edit the recipe, the component’s state will change. The button you use to save should call your edit function, just passing in the new recipe from the component’s state, eg

function handleEdit() {
    this.props.onEditRecipe(this.state); // this function had the index bound in the RecipeBoxContainer component.
}

The problem with this plan is that you’d need to make a non-trivial change - instead of passing your recipes to the Recipe component and having it render each element, you’d probably need to move that iteration into the RecipeBoxContainer component, eg

this.state.recipes.map((recipe, i) => <Recipe recipe={recipe} onEditRecipe={this.editRecipe.bind(this, i)} />);

There are some details you’ll have to work out for yourself, but that’s the gist of how I would do it.


#5

Thank you! I will try the way u told me.