Javascript 如何使for循环在组件内部的属性中工作

Javascript 如何使for循环在组件内部的属性中工作,javascript,reactjs,Javascript,Reactjs,这是一个应用程序,当点击添加配方按钮时,会弹出一个窗口。这允许您将配方名称和配方成分放入输入框。按下弹出框中的“添加配方”按钮应呈现存储在localStorage中的配方名称 现在,我的配方列表使用一个名为list的空数组,并使用for循环将localStorage项添加到列表数组中。现在,虽然它只在页面加载时起作用,但在单击“添加配方”按钮时不起作用。这是因为它无法更新数组,因为我当前将它放在组件外部,但将其放入后,它不会加载任何列表项 有关组成部分: var React = require(

这是一个应用程序,当点击添加配方按钮时,会弹出一个窗口。这允许您将配方名称和配方成分放入输入框。按下弹出框中的“添加配方”按钮应呈现存储在localStorage中的配方名称

现在,我的配方列表使用一个名为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;
var React=require(“React”);
var Recipe=React.createClass({
getInitialState:函数(){
返回{
名单:“”
};  
},
updateList:function(){
var列表=[];
对于(设i=0;i

完整代码:

我检查了您的代码,您可以将popubox.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>            
  );
})}
{this.state.list.map(函数(项,idx){
返回(
{item.name}
);
})}

最好将所有本地存储访问保持在父组件中的一个位置,并使用道具向下传播

子组件(如“弹出窗口”)可以通过道具接收回调函数,从而向上传播某些内容

这篇官方文章很好地解释了这一点:

这是一个非常简单的例子:

类应用程序扩展了React.Component{
建造师(道具){
超级(道具)
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})
}
添加配方(配方){
const recipes=[…this.state.recipes,recipe]
this.setState({recipes:recipes})
window.localStorage.setItem('recipes',JSON.stringify(recipes))
}
删除所有配方(配方){
this.setState({recipes:[]})
window.localStorage.setItem('recipes',JSON.stringify([]))
}
组件willmount(){
这是loadRecipes()
}
render(){
返回(
)
}
}
类RecipesList扩展了React.Component{
render(){
返回(
食谱
    {this.props.recipes.map((recipe,idx)=>
  • {recipe.name}
  • )}
) } } 类RecipeAdd扩展了React.Component{ 添加(){ const name=window.prompt(“recepe name:”) this.props.onRecepeded({name:name}) } render(){ 返回添加 } } 类RecipeDeleteAll扩展React.Component{ deleteAll(){ 如果(确认('全部删除?')){ this.props.onRecepesDeleted() } } render(){ 返回删除全部 } } ReactDOM.render(,document.getElementById('root'))
你的问题相当模糊。我建议你看一看,我重新编写了它,试图让它更有意义。我尝试了这段代码,我得到一个控制台错误“this.state.list.map不是函数”。是否有代码链接和所有插入的代码?也许我没有正确地插入所有内容。在getInitialState中,请尝试将列表:“更改为列表:[]该链接在如何构建应用程序方面非常有用,谢谢!至于你的代码,我很难真正理解,因为我还没有学会ES6。我不想同时学习框架和新语法。如果我忘了ES6,请告诉我。非常感谢。我会检查一下,看看我是否能尝试更好地构建这个应用程序。
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'))