这是一个应用程序,当点击添加配方按钮时,会弹出一个弹出窗口。这使您可以将配方名称和配方成分放入输入框中。按下该弹出框中的添加配方按钮应该呈现存储在localStorage中的配方名称。
现在我的Recipe列表使用一个名为list的空数组,并使用for循环将localStorage项添加到列表数组中。现在虽然它只适用于页面加载,而不是单击添加配方按钮时。这是因为它不能更新阵列,因为我目前在组件外部有它,但是放入它使它不加载任何列表项。
有问题的组件:
var React = require("react");
var Recipe = React.createClass({
getInitialState: function() {
return {
list: ""
};
},
updateList: function() {
var list = [];
for (let i = 0; i < window.localStorage.length - 1; i++) {
var key = window.localStorage.key(i);
list.push(window.localStorage.getItem(key));
}
this.setState({
list: list
});
},
componentDidMount: function() {
this.updateList();
},
render: function() {
return (
<div className="full-recipe">
{this.state.list.map(function(item) {
return (
<div className="recipe">
<h2>{item.name}</h2>
</div>
);
})}
<button onClick={function() { this.updateList()}}>refresh the list</button>
</div>
);
}
});
module.exports = Recipe;
完整代码:https://github.com/jeffm64/recipe-box/blob/master/src/components/recipe.js
答案 0 :(得分:0)
我检查了你的代码,你可以将popupbox.js中的addRecipe函数更改为:
addRecipe: function() {
var recipeName = document.querySelector(".recipe-name").value;
var counter = parseInt(window.localStorage.getItem("counter"));
window.localStorage.setItem("counter", counter++);
var recipes = window.localStorage.getItem("recipes");
if (!recipes)
recipes = [];
else
recipes = JSON.parse(recipes);
recipes.push({name: recipeName});
window.localStorage.setItem("recipes", JSON.stringify(recipes));
this.updateList();
},
然后更新列表:
updateList: function() {
var list = window.localStorage.getItem('recipes');
if (list)
list = JSON.parse(list);
else
list = [{}];
this.setState({
list: list
});
},
并且不要忘记渲染功能中的键
{this.state.list.map(function(item, idx) {
return (
<div className="recipe" key={idx}>
<h2>{item.name}</h2>
</div>
);
})}
答案 1 :(得分:0)
最好将所有localStorage访问保存在父组件中的一个位置,然后使用props将其传播下来。
子组件(如“弹出”)可以通过道具接收回调函数,以向上传播某些内容。
这篇官方文章精美地解释了这一点:
https://facebook.github.io/react/docs/thinking-in-react.html
这是一个非常简单的例子:
http://codepen.io/anon/pen/MbMrdL?editors=1010
class App extends React.Component{
constructor(props){
super(props)
this.state = {recipes:[]}
this.loadRecipes = this.loadRecipes.bind(this)
this.addRecipe = this.addRecipe.bind(this)
this.deleteAllRecipes = this.deleteAllRecipes.bind(this)
}
loadRecipes(){
const storedRecepes = window.localStorage.getItem('recipes')
const recipes = storedRecepes?JSON.parse(storedRecepes):[]
this.setState({recipes:recipes})
}
addRecipe(recipe){
const recipes = [...this.state.recipes, recipe]
this.setState({recipes:recipes})
window.localStorage.setItem('recipes',JSON.stringify(recipes))
}
deleteAllRecipes(recipe){
this.setState({recipes:[]})
window.localStorage.setItem('recipes',JSON.stringify([]))
}
componentWillMount(){
this.loadRecipes()
}
render(){
return (
<div>
<RecipesList recipes={this.state.recipes} />
<RecipeAdd onRecepeAdded={this.addRecipe} />
<RecipeDeleteAll onRecepesDeleted={this.deleteAllRecipes} />
</div>
)
}
}
class RecipesList extends React.Component{
render(){
return (
<div>
<h1>Recipes</h1>
<ul>
{this.props.recipes.map((recipe, idx)=>
<li key={idx}>{recipe.name}</li>
)}
</ul>
</div>)
}
}
class RecipeAdd extends React.Component{
add(){
const name = window.prompt("recepe name:")
this.props.onRecepeAdded({name:name})
}
render(){
return <button onClick={this.add.bind(this)}>Add</button>
}
}
class RecipeDeleteAll extends React.Component{
deleteAll(){
if(confirm('Delete all?')){
this.props.onRecepesDeleted()
}
}
render(){
return <button onClick={this.deleteAll.bind(this)}>Delete All</button>
}
}
ReactDOM.render(<App/>,document.getElementById('root'))