Once the user has entered a new recipe, the page needs to reload, loop through the list of recipes, and display the latest list. I know this has to be triggered with setState, which I am using. Why is it not triggering the reload?
(To see my CodePen for this, go here )
var GenerateRecipesFromList= React.createClass({
getInitialState: function(){
const defaultData = ['Spaghetti: pasta, oil, sauce, parsely, cheese', 'PB&J: PB, J']
const localData = JSON.parse(localStorage.getItem('reclist'));
return {
reclist: localData ? localData : defaultData
}
},
componentDidMount: function(){
this.loadData();
},
exposeAddRecipe: function(){
var exposeCurrentData = [];
exposeCurrentData = JSON.parse(localStorage.getItem('reclist'));
var newrecipe = prompt("Please add your next recipe", "For example, write 'PB&J: Peanutbutter, jelly, bread.'");
exposeCurrentData.push(newrecipe);
console.log(exposeCurrentData);
this.loadData();
},
loadData: function(){
return this.setState(localStorage.setItem('reclist', JSON.stringify(this.state.reclist)));
},
render: function(){
//localStorage.setItem('reclist', JSON.stringify(this.state.reclist));
var currentData = JSON.parse(localStorage.getItem('reclist'));
var rows = [];
for(var i=0; i<currentData.length; i++){
rows.push(<div id="individual"> <span>{this.state.reclist[i]}</span> <button type="button" id="btnAdd">Edit Recipe</button>
</div>);
}
return(
<div>{rows}
<button type="button" id="btnAdd" onClick={this.exposeAddRecipe}>Add Recipe</button>
</div>
);
}
});
var Footer = React.createClass({
render() {
return (
<footer>
<div id="containerfooter">
<p>Written by <a href="http://codepen.io/profaneVoodoo/full/dXBJzN/">John Gillespie</a> for FreeCodeCamp Campers. Happy Coding!</p>
</div>
</footer>
);
}
});
var DisplayRecipes = React.createClass({
render:function(){
return(
<div className = "mainDiv">
<div className="titleDiv">
<h1>Favorite Recipes</h1>
<GenerateRecipesFromList />
<Footer />
</div>
</div>
);
}
});
ReactDOM.render(
<DisplayRecipes />,
document.getElementById('Recipes')
);
jenovs
September 21, 2016, 2:14pm
2
setState
should look like this:
this.setState({
key: value
})
and you are using setItem
inside setState
, so your setState
in reality looks like this:
return this.setState()
(localStorage.setItem
has no return value)
Thanks!
Got it working now!
var GenerateRecipesFromList= React.createClass({
getInitialState: function(){
const defaultData = ['Spaghetti: pasta, oil, sauce, parsely, cheese', 'PB&J: PB, J']
const localData = JSON.parse(localStorage.getItem('reclist'));
return {
reclist: localData ? localData : defaultData
}
},
exposeAddRecipe: function(){
var exposeCurrentData = [];
exposeCurrentData = JSON.parse(localStorage.getItem('reclist'));
var newrecipe = prompt("Please add your next recipe", "For example, write 'PB&J: Peanutbutter, jelly, bread.'");
exposeCurrentData.push(newrecipe);
localStorage.setItem('reclist', JSON.stringify(exposeCurrentData));
this.setState({ reclist: exposeCurrentData})
},
render: function(){
var testData = JSON.parse(localStorage.getItem('reclist'));
if(testData === null){
localStorage.setItem('reclist', JSON.stringify(this.state.reclist));
}
var currentData = JSON.parse(localStorage.getItem('reclist'));
var rows = [];
for(var i=0; i<currentData.length; i++){
rows.push(<div id="individual"> <span>{this.state.reclist[i]}</span> <button type="button" id="btnAdd">Edit Recipe</button>
</div>);
}
return(
<div>{rows}
<button type="button" id="btnAdd" onClick={this.exposeAddRecipe}>Add Recipe</button>
</div>
);
}
});
var Footer = React.createClass({
render() {
return (
<footer>
<div id="containerfooter">
<p>Written by <a href="http://codepen.io/profaneVoodoo/full/dXBJzN/">John Gillespie</a> for FreeCodeCamp Campers. Happy Coding!</p>
</div>
</footer>
);
}
});
var DisplayRecipes = React.createClass({
render:function(){
return(
<div className = "mainDiv">
<div className="titleDiv">
<h1>Favorite Recipes</h1>
<GenerateRecipesFromList />
<Footer />
</div>
</div>
);
}
});
ReactDOM.render(
<DisplayRecipes />,
document.getElementById('Recipes')
);
jboxman
September 21, 2016, 5:18pm
4
A declarative approach I have come to prefer (abbreviated HTML):
currentData.map(function(item, i) {
return <div><span>{this.state.reclist[i]}</span><button></button></div>;
});
It lets you skip the boring work of iterating an array and instead apply a function to each item.
Actually, I just noticed you’re iterating on currentData
, but you only reference this.state.reclist
in your loop. Is this by design?
Yes. At the time it was just a quick and dirty way to get the number of iterations I needed, though my senses are telling me it may cause problems down the road.
Being a newbie to React I have not seen that approach you are taking with currentData. But it makes sense now that I see it and I will definitely incorporate it in the final version.
I have since forked the codepen and the latest version is here .
1 Like