代码之家  ›  专栏  ›  技术社区  ›  Nick Kinlen

React—根据用户在单击按钮后输入的文本更新类组件中的状态

  •  1
  • Nick Kinlen  · 技术社区  · 8 年前

    我比较新的反应和创建一个待办事项列表风格的食谱应用程序。用户应该能够添加新配方、删除现有配方或编辑现有配方。我在编写一个函数时遇到问题,该函数允许用户单击“编辑”按钮,然后向该配方项提交新的配方标题和/或新的配料。

    Here is the project onSubmit 在我的应用程序.js处理用户创建的新配方项并将其添加到列表中的文件。我现在正在尝试实现一个类似的函数 onEditSubmit 这允许用户更新现有的食谱项目,但我卡住了。

     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
        };
    
      }
    
      // 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
        });
      }
    
      // Should edit and update a recipe item when user clicks edit button and then submits RecipeEditForm, not working
      onEditSubmit = (event) => {
        event.preventDefault()
        // This setState shoul erase previous recipe state and rewrite it with the details the user entered after editing that particular recipe item
        this.setState({
          items: this.state.inputValEdit,
          ingredients: this.state.ingredientValEdit,
          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) => {
        console.log('Edit button clicked');
        console.log('index is ' + index);
        this.setState({ showRecipeEditForm: !this.state.showRecipeEditForm });
      }
    
      // 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="Recipe-List">
            <h1>Recipe List</h1>
    
            <Item
              items={this.state.items}
              ingredients={this.state.ingredients}
              edit={this.edit}
              delete={this.delete}
            />
    
            <button onClick={this.AddRecipe}>Add New Recipe</button>
    
            {/* Shows form to edit recipe */}
            { this.state.showRecipeEditForm ?
    
              <RecipeEditForm
                inputValEdit={this.state.inputValEdit}
                handleChange={this.handleChange}
                ingredientValEdit={this.state.ingredientValEdit}
                onEditSubmit={this.onEditSubmit}
                closeRecipeForm={this.closeRecipeForm}
              />
    
              :null
            }
    
            {/* Shows form to add new recipe to the list */}
            { this.state.showRecipeForm ?
    
              <RecipeForm
                inputVal={this.state.inputVal}
                handleChange={this.handleChange}
                ingredientVal={this.state.ingredientVal}
                onSubmit={this.onSubmit}
                closeRecipeForm={this.closeRecipeForm}
              />
    
              :null
            }
    
          </div>
        );
      }
    
    }
    


    这是我的项目.js数据的函数容器。这个容器在 提交 OneEdit提交 如果我尝试使用它就会出错, props.items.map is not a function .

    import React from 'react';
    
    const Item = (props) => (
      <div>
        <div className="Recipe-Item" key={props.text}>
    
            {props.items.map((item, index) =>
            <div className="Recipe-Item-Container">
            <ul>
              <li key={index}>
                {item}
              </li>
              <li>
                {props.ingredients[index]}
              </li>
            </ul>
    
              <button onClick={() => props.edit(item, index)}>Edit</button>
              <button onClick={() => props.delete(item, index)}>Delete</button>
    
            </div>
          )}
        </div>
      </div>
    )
    
    
    export default Item;
    

    编辑以更正onSubmitError函数中的语法错误:inputVal更改为inputValEdit,ingredientVal更改为ingredientValEdit

    以下是 提交 :

    import React, { Component } from 'react';
    
    
    const RecipeForm = (props) => {
      return (
        <div>
          <form className="Recipe-Form" onSubmit={props.onSubmit}>
            <p className="x-close" onClick={props.closeRecipeForm}>X</p>
            <div className="form-content">
              <label>Recipe Name</label>
    
              <input
                name="inputVal"
                value={props.inputVal}
                onChange={props.handleChange}
              />
    
              <label>Ingredients</label>
              <input
                name="ingredientVal"
                value={props.ingredientVal}
                onChange={props.handleChange}
              />
    
              <button>Submit</button>
            </div>
          </form>
        </div>
      );
    }
    
    export default RecipeForm;
    

    下面是 OneEdit提交 :

    import React, { Component } from 'react';
    
    
    const RecipeEditForm = (props) => {
      return (
        <div>
          <form className="Recipe-Form Edit-Form" onSubmit={props.onEditSubmit}>
            <p className="x-close" onClick={props.closeRecipeForm}>X</p>
            <div className="form-content">
              <h1>This is the edit form</h1>
    
              <label>Edit Recipe</label>
              <input
                name="inputValEdit"
                value={props.inputValEdit}
                onChange={props.handleChange}
              />
    
              <label>Ingredients</label>
              <input
                name="ingredientValEdit"
                value={props.ingredientValEdit}
                onChange={props.handleChange}
              />
    
              <button>Submit</button>
            </div>
          </form>
        </div>
      );
    }
    
    export default RecipeEditForm;
    
    2 回复  |  直到 8 年前
        1
  •  2
  •   izb    8 年前
    onEditSubmit = (event) => {
      event.preventDefault()
      // This setState shoul erase previous recipe state and rewrite it with the 
      details the user entered after editing that particular recipe item
      this.setState({
        items: this.state.inputVal,
        ingredients: this.state.ingredientVal,
        showRecipeEditForm: false
      });
    }
    

    你在设置 items 状态字段转换为字符串。您应该将其更改为:

    onEditSubmit = (e) => {
      e.preventDefault();
      const {items, ingredients, inputVal, ingredientVal, editingIndex} = this.state;
      items[editingIndex] = inputVal;
      ingredients[editingIndex] = ingredientVal;
      this.setState({
        items,
        ingredients,
        inputVal: '',
        ingredientVal: ''
      });
    }
    

    editingIndex edit 功能: setState({editingIndex: index}

        2
  •  0
  •   Dacre Denny    8 年前

    你需要延长你的时间 <App/>

    onEditSubmit() 功能:

     onEditSubmit = (event) => {
        event.preventDefault()
    
        // Get the index of the recipe we're currently editing
        const currentlyEditingIndex = this.state.currentlyEditingIndex
    
        // Clone data arrays for mutation
        const items = [].concat(this.state.items)
        const ingredients = [].concat(this.state.ingredients)
    
        // Update data arrays
        items[ currentlyEditingIndex ] = this.state.inputValEdit;
        ingredients[ currentlyEditingIndex ] = this.state.ingredientValEdit;
    
        this.setState({
           items: items,
           ingredients: ingredients,
          showRecipeEditForm: false
        });
      }
    

    要使其工作,您还需要更新 edit 功能如下:

    edit = (item, index) => {
        console.log('Edit button clicked');
        console.log('index is ' + index);
        this.setState({ 
    
           // Store the index of the recipe being edited
           currentlyEditingIndex : index, 
           showRecipeEditForm: !this.state.showRecipeEditForm 
        });
      }