Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React-使用map函数遍历状态_Javascript_Reactjs_Iteration_State_Setstate - Fatal编程技术网

Javascript React-使用map函数遍历状态

Javascript React-使用map函数遍历状态,javascript,reactjs,iteration,state,setstate,Javascript,Reactjs,Iteration,State,Setstate,我是一个比较新的反应和创造托多利斯特风格。用户应该能够向列表中添加新配方,以及删除或编辑现有配方 我遇到了一个问题,那就是如何在不同的行中显示成分,以及如何做到这一点。最终的结果是,我在容器中添加了第二个.map函数来迭代成分,并将每个成分显示为一个新的段落元素。这是我的容器,Item.js: import React from 'react'; import Button from 'react-bootstrap/lib/Button'; const Item = (props) =&g

我是一个比较新的反应和创造托多利斯特风格。用户应该能够向列表中添加新配方,以及删除或编辑现有配方

我遇到了一个问题,那就是如何在不同的行中显示成分,以及如何做到这一点。最终的结果是,我在容器中添加了第二个
.map
函数来迭代成分,并将每个成分显示为一个新的段落元素。这是我的容器,
Item.js

import React from 'react';
import Button from 'react-bootstrap/lib/Button';


const Item = (props) => (
  <div>
    <div className="Recipe-Item-Container" key={props.text}>
      {/* Iterates through recipe item names and displays them */}
      {props.items.map((item, index) => {
        return (
        <div className="Recipe-Item" key={index}>
          <h3>{item}</h3>

         // This is what I added
        {/* Iterates through recipe ingredients and displays them*/}
        <p className="ingredients-list">
          {props.ingredients[index].map((ingredient, ingredientIndex) => {
            return (
              <div className="ingredient" key={ingredient}>
                {ingredient}
              </div>
            )
          })}
        </p>

        <div className="buttons-container">
          <Button className="edit-button" onClick={() => props.edit(item, index)}>Edit</Button>
          <Button className="delete-button" onClick={() => props.delete(item, index)}>Delete</Button>
          </div>
        </div>
      );
    }
  )}
  </div>
</div>
)

export default Item;
import React, { Component } from 'react';
import Item from './Item';
import './App.css';
import ModalComponent from './Modal.js';
import Button from 'react-bootstrap/lib/Button';
import EditModalComponent from './EditModal.js';
import SimpleStorage from "react-simple-storage";


export default class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      items: ["Pumpkin Pie", "Spaghetti", "Onion Pie"],
      ingredients:[
        ["Pumpkin Puree ", "Sweetened Condensed Milk ", "Eggs ", "Pumpkin Pie Spice ", "Pie Crust "],
        ["Noodles ", "Tomato Sauce ", "(Optional) Meatballs "],
        ["Onion ", "Pie Crust "]
      ],

      // Recipe name and ingredients
      inputVal: '',
      ingredientVal: '',
      // Recipe name and ingredients when user is editing existing recipe
      inputValEdit: '',
      ingredientValEdit: '',
      // Controls whether forms are displayed or hidden
      showRecipeForm: false,
      showRecipeEditForm: false,
      // Index to select which recipe item is being edited
      editingIndex: ''
    };

  }

  // Get text user inputs for recipes
  handleChange = (event) => {
    this.setState({ [event.target.name]: event.target.value });
  };


  // When user submits recipe this adds it to the list
  onSubmit = (event) => {
    event.preventDefault();

    this.setState({
      items: [...this.state.items, this.state.inputVal],
      ingredients: [...this.state.ingredients, [this.state.ingredientVal]],
      showRecipeForm: false
    });

  }

  // When user edits existing recipe this adds it to the list
  onEditSubmit = (event) => {
    event.preventDefault();
    const {items, ingredients, inputValEdit, ingredientValEdit, editingIndex} = this.state;

    // Selects proper recipe item to edit
    items[editingIndex] = inputValEdit;
    ingredients[editingIndex] = ingredientValEdit.split(',');


    this.setState({
      items: items,
      ingredients: ingredients,
      inputVal: '',
      ingredientVal: '',
      showRecipeEditForm: false
    });
  }

  closeRecipeForm = () => {
    this.setState({
      showRecipeForm: false,
      showRecipeEditForm: false
    });
  }

  // Shows recipe
  AddRecipe = (bool) => {
    this.setState({
      showRecipeForm: bool
    });
  }

  // Is called when one of the edit recipe buttons is clicked, shows RecipeEditForm
  edit = (item, index) => {
    this.setState({
      showRecipeEditForm: !this.state.showRecipeEditForm,
      editingIndex: index
    });
  }

  // Deletes recipe item from the list
  delete = (item, index) => {
     this.setState({
      ingredients : this.state.ingredients.filter((_, i) => i !== index),
      items: this.state.items.filter((_, i) => i !== index)
    });
  }


  render() {
    return (
      <div className="container">

        {/* Handles storing data in local sessions via react-simple-storage*/}
        <SimpleStorage parent={this} />

        <h1>Recipe List</h1>


        <ModalComponent
          inputVal={this.state.inputVal}
          handleChange={this.handleChange}
          ingredientVal={this.state.ingredientVal}
          onSubmit={this.onSubmit}
          addRecipe={this.addRecipe}
          showRecipeForm={this.state.showRecipeForm}
          closeRecipeForm={this.closeRecipeForm}
        />

        <EditModalComponent
          inputValEdit={this.state.inputValEdit}
          handleChange={this.handleChange}
          ingredientValEdit={this.state.ingredientValEdit}
          onEditSubmit={this.onEditSubmit}
          closeRecipeForm={this.closeRecipeForm}
          addRecipe={this.addRecipe}
          showRecipeEditForm={this.state.showRecipeEditForm}
        />


        <Item
          items={this.state.items}
          ingredients={this.state.ingredients}
          edit={this.edit}
          delete={this.delete}
        />

      <Button className="add-recipe-button" onClick={this.AddRecipe}>Add New Recipe</Button>

      </div>
    );
  }

}

我是否需要使
onSubmit
更类似于
onEditSubmit
?如果是这样,我该怎么做呢?

在您的商店中,您的配料变量是一个数组数组。
[[a,b],[c,d]

您需要像在onEditSubmit中一样遵循此格式。
.split()
函数返回一个数组并将其保存到状态

更改onSubmit中的部件

this.setState({
    items: [...this.state.items, this.state.inputVal],
    ingredients: [...this.state.ingredients, [this.state.ingredientVal]],
    showRecipeForm: false
});


不清楚
this.ingredientVal
变量是什么,如果它是一个与
ingredientValEdit
格式相同的
字符串,则需要使用
[…this.state.components,this.state.ingredientVal.split(“,”)
而不是
[…this.state.components,[this.state.ingredientVal]]
我遇到了这个问题,我的状态是字符串/数组:是的,但您使用的是
成分:[…this.state.components,this.state.ingredientVal]
不是
成分:[…this.state.components,this.state.ingredientVal.split(“,”)
。这似乎已经成功了。我对我以前做的改变感到困惑,这似乎就是问题所在。谢谢
this.setState({
    items: [...this.state.items, this.state.inputVal],
    ingredients: [...this.state.ingredients, this.state.ingredientVal.split(',')],
    showRecipeForm: false
});