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

React—将函数作为道具传递给功能组件时出现“不是函数”错误

  •  0
  • Nick Kinlen  · 技术社区  · 7 年前

    Recipe app a previous question here 关于重构一个功能组件,使配方成分出现在单独的行中,而不是全部出现在一个单行段落中。

    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}>
          {props.items.map((item, index) => {
            return (
            <div className="Recipe-Item" key={index}>
              <h3>{item}</h3>
    
            // This p and the map function within it were the changes I made
            <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;
    

    现在,当我单击“编辑”按钮并尝试编辑配料列表时,出现以下错误:

    Error showing when user attempts to edit ingredients

    这是我的App.js 存储状态并向其传递数据的组件Item.js:

    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';
    
    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
        });
      }
    
      onEditSubmit = (event) => {
        event.preventDefault();
        const {items, ingredients, inputValEdit, ingredientValEdit, editingIndex} = this.state;
    
        // Selects proper recipe item to edit
        items[editingIndex] = inputValEdit;
        ingredients[editingIndex] = ingredientValEdit;
    
        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">
            <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>
        );
      }
    
    }
    

    Item.js 当用户试图编辑成分列表时?我认为这涉及到 onEditSubmit

    1 回复  |  直到 7 年前
        1
  •  1
  •   Sivcan Singh    7 年前

    所以,我在你的脸上看到了 onEditSubmit 你这样做:

    ingredients[editingIndex] = ingredientValEdit; // line 57
    

    是这样的:

    ingredients:[
            ["Pumpkin Puree ", "Sweetened Condensed Milk ", "Eggs ", "Pumpkin Pie Spice ", "Pie Crust "],
            ["Noodles ", "Tomato Sauce ", "(Optional) Meatballs "],
            ["Onion ", "Pie Crust "]
          ],
    

    我加入了“鸡棒棒糖”作为例如的配料。

    ingredients:[
            "Chicken Lollipop",
            ["Noodles ", "Tomato Sauce ", "(Optional) Meatballs "],
            ["Onion ", "Pie Crust "]
          ],
    

    在本例中,索引0处的值现在是一个字符串。

    因此,在 Item.js

    要解决此问题,可以将第57行更改为:

    ingredients[editingIndex] = [ingredientValEdit];
    

    现在,每个条目都将正确地存储为一个数组,您的代码应该可以正常工作。 更新后的数组如下所示:

    ingredients:[
            ["Chicken Lollipop"],
            ["Noodles ", "Tomato Sauce ", "(Optional) Meatballs "],
            ["Onion ", "Pie Crust "]
          ]
    

    其他内容(此答案不需要):

    但是,由于总是需要将成分作为数组,因此也可以使用分隔符拆分输入值,例如:

    用户输入的配料是:“棒棒糖,糖果,什么的”

    在第57行中,您还可以执行以下操作:

    ingredients[editingIndex] = ingredientValEdit.split(',');
    
    推荐文章