When I run this code, I get a bootstrap panel group for each recipe item inside of local storage. When I try to delete a recipe, sometimes the right recipe is removed and sometimes not. The console shows that the right recipe is removed from local storage but for some reason when the app component resets its state, the wrong recipe is removed. I've noticed that if I try to delete the recipes from the bottom up, it works. But if I click on the first recipe, the bottom recipe is removed.
I know this is an easy fix but I need a fresh perspective. Thanks everyone! Also, sorry lack of indentation in the code - stack overflow wasn't being too friendly with the spacing
class App extends Component {
constructor() {
super();
this.deleteRecipe = this.deleteRecipe.bind(this)
this.state = {
recipeData: JSON.parse(localStorage.getItem('recipeData'))
}
}
deleteRecipe() {
this.setState({recipeData: JSON.parse(localStorage.getItem('recipeData'))})
}
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React Recipe Box!</h2>
</div>
<div className="container">
{this.state.recipeData.map(recipe => {
return (
<Recipe name={recipe.name} ingredients={recipe.ingredients} deleteRecipe={this.deleteRecipe}/>
)
})}
</div>
</div>
);
}
}
class Recipe extends Component {
constructor() {
super();
this.onDeleteRecipe = this.onDeleteRecipe.bind(this)
}
componentWillMount(){ //set state when component is about to mount
this.state = {
name: this.props.name,
ingredients: this.props.ingredients,
}
}
onDeleteRecipe() {
var recipeList = JSON.parse(localStorage.getItem('recipeData'));
for(var i = 0; i < recipeList.length; i++) {
if(recipeList[i].name === this.state.name) {
recipeList.splice(i, 1);
console.log("Deleted " + this.state.name, recipeList);
localStorage.removeItem('recipeData');
localStorage.setItem('recipeData', JSON.stringify(recipeList));
this.props.deleteRecipe();
}
}
}
render() {
return (
<div>
<div className="panel-group">
<div className="panel panel-primary">
<div className="panel-heading">
<h2 className="panel-title">
<a data-toggle="collapse" data-target={'#' + (this.state.name).replace(/\s/g, '')} href={'#' + (this.state.name).replace(/\s/g, '')}>
{this.state.name}
</a>
</h2>>
</div>
<div id={(this.state.name).replace(/\s/g,'')} className="panel-collapse collapse">
<div className="panel-body">
{this.state.ingredients.map(ingredient => {
return <li className="list-group-item">{ingredient}</li>
})}
<div className="btn-group">
<button className="btn btn-sm btn-info" data-toggle="modal"
data-target={'#' + (this.state.name).replace(/\s/g, '') + 'EditModal'}>Edit</button>
<button className="btn btn-sm btn-danger" data-toggle="modal"
data-target={'#' + (this.state.name).replace(/\s/g, '') + 'RemoveModal'}
>Delete</button>
</div>
</div>
</div>
</div>
</div>
<div className="modal modal-lg" id={(this.state.name).replace(/\s/g, '') + 'EditModal'} >
<div className="modal-content">
<div className="modal-header">
<h2>Edit {this.state.name}</h2>
</div>
<div className="modal-body">
<ul className="list-group list-unstyle">
{this.state.ingredients.map( ingredient => {
return <li className="list-group-item">{ingredient}</li>
})}
</ul>
</div>
<div className="modal-footer">
<div className="btn-group">
<button className="btn btn-sm btn-info" data-dismiss="modal">Save</button>
<button className="btn btn-sm btn-danger" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div className="modal modal-lg" id={this.state.name.replace(/\s/g, '') + 'RemoveModal'}>
<div className="modal-content">
<div className="modal-body">
<h3>This will remove the selected recipe. Are you sure?</h3>
</div>
<div className="modal-footer">
<div className="btn-group">
<button className="btn btn-sm btn-danger" data-dismiss="modal" onClick={this.onDeleteRecipe}>Delete</button>
<button className="btn btn-sm btn-info" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default App;