Reputation: 688
I’d like your insight with my attempt at creating a Recipe Box.
https://codepen.io/gianndall/pen/evyBYd?editors=0010
class RecipeList extends React.Component {
constructor(props) {
super(props);
this.state = {
}
}
render() {
var list = JSON.parse(this.props.recipes);
console.log (list);
return (
<ul className="collection">
{list.map( (x) =>
<li className="collection-item">
<div>
{x.name} {list.indexOf(x)}
<a href="#!" className="secondary-content">
<i className="material-icons"
onClick = {() => this.props.deleteIt(list.indexOf(x))}
>delete</i></a>
<a href="#!" className="secondary-content"><i className="material-icons">edit</i></a>
</div>
</li> )}
</ul>
)
}
}
class AddRecipeModal extends React.Component {
constructor(props) {
super(props);
this.state = {
input1: '',
textarea1: ''
}
}
handleChangeTextarea(event) {
this.setState({textarea1: event.target.value});
}
handleChangeInput(event) {
this.setState({input1: event.target.value});
}
handleSubmit(event) {
alert('A recipe was submitted: ' + this.state.input1 + ' '+ this.state.textarea1);
event.preventDefault();
if(typeof(Storage) !== "undefined") {
console.log(localStorage.Recipes);
if (localStorage.Recipes){
var newRecipe = this.state.input1;
var newIngredient = this.state.textarea1.split(',');
console.log( 'vers 2' , newRecipe);
var x = JSON.parse( localStorage.Recipes );
console.log('vers 2' , x);
x.push(
{name:newRecipe,
contans: newIngredient
}
);
var updated = localStorage
.setItem('Recipes',JSON.stringify(x));
}else{
var i=[];
var newRecipe = this.state.input1;
var newIngredient = this.state.textarea1.split(',');
i.push(
{name:newRecipe,
contans: newIngredient
}
);
localStorage
.setItem('Recipes',JSON.stringify(i));
console.log('vers 1 i= ',i);
console.log('vers1 RECIPES ', localStorage.Recipes);
}
}else{
alert("Sorry, your browser does not support web storage...");
}
console.log('test');
{this.props.closeIt()}
}
render() {
return(
<div id="modal1" className= {'modal ' + (this.props.display ? 'open' : '') }>
<div className="modal-content">
<h4>Add Recipe</h4>
<form onSubmit={this.handleSubmit.bind(this)} >
<div className="input-field" >
<input id="input1" type="text" value={this.state.input1} onChange={this.handleChangeInput.bind(this)} />
<label for="first_name">Recipe Name</label>
</div>
<div className="input-field" >
<textarea id="textarea1" className="materialize-textarea" value={this.state.textarea1} onChange={this.handleChangeTextarea.bind(this)} />
<label for="textarea1">Ingredient - separate with comma:</label>
</div>
<button type="Submit" className="waves-effect waves-light btn"><i className="material-icons left">add</i>Add it</button>
</form>
</div>
<div className="modal-footer">
<a href="#!" className="modal-action modal-close waves-effect waves-green btn-flat" onClick={this.props.closeIt}>Cancel</a>
</div>
</div>
)
}
}
class RecipesBox extends React.Component {
constructor(props) {
super(props);
this.state = {
modalShow: false
}
}
openModal(){
this.setState({
modalShow: true
})
}
closeModal(){
this.setState({
modalShow: false
})
}
deleteRecipe(x) {
console.log('test', x);
var list = JSON.parse(localStorage.Recipes);
list.splice(x,1);
console.log('list =',list);
localStorage.Recipes = JSON.stringify(list);
};
render() {
const listed = localStorage.Recipes ?
<RecipeList recipes={localStorage.Recipes} deletIt={this.deleteRecipe}/> :
<ul className="collection"><li className="collection-item">The Recipe Box is empty</li>
</ul>
return (
<div>
<nav className="nav-extended">
<div className="nav-content">
<span className="nav-title">Recipe Box</span>
<a className="btn-floating btn-large halfway-fab waves-effect waves-light teal" onClick={this.openModal.bind(this)}>
<i className="material-icons">add</i>
</a>
</div>
</nav>
{listed}
< AddRecipeModal display={this.state.modalShow} closeIt ={this.closeModal.bind(this)}/>
</div>
)
}
}
class newRecipe extends React.Component {}
ReactDOM.render(
< RecipesBox />,
document.getElementById('app')
);
After few days of reading and frustration, I can’t delete the list item. I have a problem creating a props function with arguments that passes a value from child to parent (specifically the local storage array index).
I keep getting a _this2.props.deleteIt is not a function
error
I can, of course, create a massive Component and make my life easier, but that’s not the point. I want to learn how to handle smaller components
I’d really hope you can provide a fresh look on this.
Thank you
Upvotes: 0
Views: 604
Reputation: 4464
As your component will not trigger a render on deletion, i suggest you 3 options :
Edit : Try to avoid forceUpdate(), from official doc :
Normally you should try to avoid all uses of forceUpdate() and only read from this.props and this.state in render().
Upvotes: 1
Reputation: 10536
You have to pass it in as deleteIt
, not deletIt
:
<RecipeList deletIt={this.deleteRecipe} />
should be
<RecipeList deleteIt={this.deleteRecipe} />
Also, in the future you may need to reference this
inside of the deleteRecipe
method. So at that point you may want to use an arrow function or .bind
.
Upvotes: 2
Reputation: 4008
Well, it looks like you mistyped something:
<RecipeList recipes={localStorage.Recipes} deletIt={this.deleteRecipe}/> :
Should be like this:
<RecipeList recipes={localStorage.Recipes} deleteIt={this.deleteRecipe}/> :
Upvotes: 1