javascript - 当编辑状态为 true 时,如何让我的添加函数仅更改所选索引的内容?

标签 javascript reactjs jsx

当编辑状态为 true 时,我希望这样当用户点击“提交”时,他们选择编辑的项目就会发生更改。通常,如果用户不在编辑模式下,它会添加一个新对象。然而,由于某种原因,即使我为特定索引调用 splice,它也只会更改第一个索引。我也尝试过将按钮绑定(bind)到 i 但仍然没有成功。

  const {
    Modal,
    Input,
    Button
  } = ReactBootstrap;

  var modalName = "Add New Recipe";
  var editRecipe = "";
  var editIngredient = [];

  var Recipes = React.createClass({
  // hook up data model
  getInitialState: function() {
    return {
      showModal: false,
      editing: false,
      recipeList: [
          {recipe: "Malek's Protein Shake", ingredients: ['1 Glass of Whole Milk', '6 tablespoons of Peanut Butter', '1 scoop of Whey', '2 Bananas', '1 scoop of Vanilla Ice Cream']},
          {recipe: 'Pumpkin Pie', ingredients: ['Pumpkin Puree', 'Sweetened Condensed Milk', 'Eggs', 'Pumpkin Pie Spice', 'Pie Crust']},
          {recipe: 'Spaghetti with fried eggs', ingredients: ['Noodles', 'Tomato Sauce', 'Meatballs', '4 eggs', 'Ground black pepper']}
        ]
    }
  },

  ingredientList: function(ingredients) {
   return ingredients.map((ingredient, i) => {
    return (<li key={i} index={i} className="list-group-item">{ingredient}</li>)
   })
  },

  eachRecipe: function(item, i) {
    return (
        <div key={i} index={i} className="panel panel-default">
          <div className="panel-heading"><h3 className="panel-title">{item.recipe}</h3></div>
          <div className="panel-body">
            <ul className="list-group">
              {this.ingredientList(item.ingredients)}
            </ul>
            <button name={i} onClick={this.edit.bind(this, i)} type="button" className="btn-sm btn-info" data-toggle="modal" data-target="#myModal">Edit</button>
            <button onClick={this.remove.bind(this, i)} type="button" className="btn-sm btn-danger">Remove</button>
          </div>
        </div>
    )
  },

  add: function(i) {
    var name = this.refs.userVal.value;
    var items = this.refs.newIngredients.value.split(",");
    if (this.state.editing) {
      var cloneEdit = this.state.recipeList.slice();
      cloneEdit.splice(i, 1, { recipe: name, ingredients: items });
      this.setState({recipeList: cloneEdit});
    }
    else {
      this.setState({recipeList: [...this.state.recipeList, { recipe: name, ingredients: items }]})
    }
    this.close();
  },

  edit: function(i, recipe, ingredients) {
    this.setState({editing: true})
    this.open();
    modalName = "Edit";
    var arr = this.state.recipeList.slice();
    editRecipe = arr[i].recipe;
    editIngredient = arr[i].ingredients;
  },

  remove: function(i) {
    var arr = this.state.recipeList.slice(); //copy array
    arr.splice(i, 1); //remove element
    this.setState({recipeList: arr}); //update state
  },

  close() {
    this.setState({editing: false});
    this.setState({ showModal: false });
    modalName = "Add New Recipe";
    editRecipe = "";
    editIngredient = "";
  },

  open() {
    this.setState({ showModal: true });
  },

  render: function() {
      return (
        <div>
        <div>
        <button onClick={this.open} type="button" className="btn btn-success btn-lg" data-toggle="modal" data-target="#myModal">Add Recipe</button>
        <Modal show={this.state.showModal} onHide={this.close}>
          <Modal.Header closeButton>
            <Modal.Title>{modalName}</Modal.Title>
          </Modal.Header>
          <Modal.Body>
            <form>
              <div className="form-group">
                <label for="name">Recipe</label>
                <input type="text" ref="userVal" className="form-control" id="name" placeholder="Recipe Name" defaultValue={editRecipe} required />
              </div>
              <div className="form-group">
                <label for="ingredients">Ingredients</label>
                <input type="text" ref="newIngredients" className="form-control" id="ingredients" placeholder="Enter Ingredients,Separated,By,Commas" defaultValue={editIngredient} required />
              </div>
            </form>
          </Modal.Body>
          <Modal.Footer>
            <Button className="btn btn-primary" data-dismiss="modal" onClick={this.add}>Submit</Button>
            <Button className="btn btn-default" onClick={this.close}>Close</Button>
          </Modal.Footer>
        </Modal>
    <div className="panelArea">
        {
          this.state.recipeList.map(this.eachRecipe)
        }
    </div>
        </div>
        </div>
      );
    }
});

ReactDOM.render(
  <Recipes />,
  document.getElementById('master')
)

最佳答案

您没有捕获正在编辑的项目的索引,因此 this.add 将获取分配给 i 的点击事件。因此,splice 不会按预期工作。

我建议将诸如 editIdx 之类的内容保留在状态中:

class YourComponet extends React.Component {

  // ...

  edit(i, recipe, ingredients) {
    this.setState({
      editing: true,
      editIdx: i
    });
    // ...
    this.open();
  }

  add() {
    // ...
    if (this.state.editing) {
      var i = this.state.editIdx;
      var cloneEdit = this.state.recipeList.slice();
      cloneEdit.splice(i, 1, { recipe: name, ingredients: items });
      this.setState({recipeList: cloneEdit});
    } else {
      this.setState({recipeList: [...this.state.recipeList, { recipe: name, ingredients: items }]})
    }
    this.close();
  }
}

关于javascript - 当编辑状态为 true 时,如何让我的添加函数仅更改所选索引的内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39884622/

相关文章:

javascript - Next JS 和 Vercel - 开发与生产

reactjs - Ember 应用程序中的状态管理

javascript - React Web 应用程序中缺少滚动条

javascript - 在javascript类中获取文档计数列表

javascript - Angularjs - 无法读取未定义的属性 'split'

javascript - 自动制作 bootstrap 垂直导航丸

reactjs - 在 Jest : NavigationContainer causes console error 中异步测试 React Navigation 5

javascript - CSS 位置固定不起作用 - 粘性导航

javascript - 如果为真,则 react 显示这些 div

javascript - React Native - 使用动态名称的图像需要模块