Updating state from child component onclick

Updating state from child component onclick
0

#1

So, I am just trying to get the skeleton working…well idea of the skeleton for the app I want to re try. Now I am trying to update the state from the child component…I think I passed in the state as props correctly, but to be honest im not sure about the actual updating part. the handle change method will capture the input, and then im assuming the submit will set the state name to the input. Essentially it will be where the user can edit the recipe not just the name…but baby steps. of course I only wanted one name to change, but wasnt quite sure in the onsubmit method. Will take any help here

class RecipeBox extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input:'',
     recipeList :
      [{
        recipe: "Tacos",
        directions: "make tacos",
        ingredients: ["meat"]
      },
      {
        recipe: "pizza",
        directions: "bake",
        ingredients: ["dough"]
      }]
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }///
  
  handleChange(event) {
    this.setState({
      input: event.target.value
    });
   }
  
  handleSubmit(e){
    e.prevent.Default
    setState({
      recipe: input
    })
  }
  
  render(){
    const {input} = this.state;
    const ITEMS = this.state.recipeList.map(({directions}) => <li>{directions}</li>)
    return(
      <div>
        <EditList input = {this.state.input}
          handleChange = {this.handleChange}
          onSubmit = {this.handleSubmit}/>
          <ul>                                                     
          {ITEMS}
          </ul>
        </div>
    )
  }
}

class EditList extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return(
      <div>
        <input type='text'
          value ={this.props.input}
          onchange = {this.props.handleChange}
         />
        <button onClick={this.props.onSubmit}>Submit</button>
       </div>
     )
  }
}

ReactDOM.render(<RecipeBox />, document.getElementById('app'));

#2

Check this out. It will help you.


#3

Appreciate. I stepped out to take a break, but will look st it when I get back!!


#4

This should be onChange and not onchange.

I think you meant to write e.preventDefault(); to prevent a form from submitting. Actually, this is not necessary, because you do not even have a form element in your code.

Above, you attempt to assign a variable input to a property named recipe using setState, but input is not defined in the handleSubmit function. Also, it should be this.setState and not setState.

What exactly are you try to accomplish in this function?


#5

Input I actually made in state…now that I think about it I’m not sure why…

I know the handle change would capture whatever the user entered, so here after they hit submit I wanted that input to replace the name of the recipe. Though selecting one I wasn’t sure about.

The end goal is to have a user select a recipe and be able to edit that specific recipe, so I will have to find out to make sure it’s that’s specific recipe state being edited. But obviously that’s a long shot from now


#6

Made some changes…still wrong I know that, but maybe closer? Right now like I said basically I just want to change one recipe name in the list when the user enters and hits the button. I grabbed the two methods from the parent component, and the recipe state I think. Not sure if I need that to update the state, or will the methods take care of it? Of course it does not like mt handle and submit methods the way they are now

class RecipeBox extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      
     recipeList :
      [{
        recipe: "Tacos",
        directions: "make tacos",
        ingredients: ["meat"]
      },
      {
        recipe: "pizza",
        directions: "bake",
        ingredients: ["dough"]
      }]
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }///
  
  handleChange(event) {
    this.setState({
     recipeList[0].recipe :event.target.value
    });
   }
  
  handleSubmit(){
      const newRecipe = this.state.recipelist[0].recipe
    setState({
      recipeList[0].recipe: newRecipe
      
    })
  }
  
  render(){
   const input = '';
    const ITEMS = this.state.recipeList.map(({recipe}) => <li>{recipe}</li>)
    return(
      <div>
        <EditList recipe = {this.state.recipeList[0].recipe}
          handleChange = {this.handleChange}
          onSubmit = {this.handleSubmit}/>
          <ul>                                                     
          {ITEMS}
          </ul>
        </div>
    )
  }
}

class EditList extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
     
    return(
      <div>
        <input type='text'
          value = {input}
          onChange = {this.props.handleChange}
         />
        <button onClick={this.props.onSubmit}>Submit</button>
       </div>
     )
  }
}

ReactDOM.render(<RecipeBox />, document.getElementById('app'));

#7

OK, you still have not fixed some of the problems I pointed out earlier and created additional problems for code that was working fine.

#1) You must use this.setState and not just setState in the handleSubmit

#2) You should not have changed your handleChange method at all. Also, you should have left in the input property in your this.state initialization which is used by handleChange.

#3) Once you have resolved #2 above, then you can change your EditList back to:

class EditList extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div>
        <input
          type="text"
          value={this.props.input}
          onChange={this.props.handleChange}
        />
        <button onClick={this.props.onSubmit}>Submit</button>
      </div>
    );
  }
}

#4) For the handleSubmit method, you are trying to update the state of a nested array. You can not write: recipeList[0].recipe: newRecipe, but you first create a copy of the full recipeList array in this.state and the modify the recipe value of the first element of the new copied array and then assign this modified array back to this.state.recipeList. Also, you need to make sure you set the input property back to a blank string, so after clicking Submit, the textbox is empty.

  handleSubmit() {
    const recipeList = [...this.state.recipeList];
    recipeList[0].recipe = this.state.input;
    this.setState({
      recipeList,
      input: ""
    });
  }

#8

A question if I may.

the creating of the copy or shallow array in handle submit is because of mutating right? Or rather not mutating the original array? So if I want to update or make any changes to an array I must always do that on the copy


#9

It is not so much a matter of not mutating the original array (though that is important). Instead, it is because you can not update nested properties in state in the way you are trying. You must create another array/object and then modify the element/property and then set the state for all the properties at the same time.