2016-10-01 116 views
-1

我想獲得用戶輸入到模態輸入框的值,然後將它們添加到我的狀態數組中。我嘗試從輸入中獲取值,然後將它們推入我的狀態數組的克隆中,然後將狀態設置爲克隆。但是,這種方法似乎並不奏效。我很感激,如果任何人能chime英寸爲什麼我的添加功能不起作用?

var Recipes = React.createClass({ 
    // hook up data model 
    getInitialState: function() { 
     return { 
     recipeList: [ 
      {recipe: 'Cookies', ingredients: ['Flour', 'Chocolate']}, 
      {recipe: 'Pumpkin Pie', ingredients: ['Pumpkin Puree', 'Sweetened Condensed Milk', 'Eggs', 'Pumpkin Pie Spice', 'Pie Crust']}, 
      {recipe: 'Onion Pie', ingredients: ['Onion', 'Pie-Crust']}, 
      {recipe: 'Spaghetti', ingredients: ['Noodles', 'Tomato Sauce', 'Meatballs']} 
      ] 
     } 
    }, 

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

    eachRecipe: function(item, i) { 
     return (
      <div className="panel panel-default"> 
      <div className="panel-heading"><h3 key={i} index={i} className="panel-title">{item.recipe}</h3></div> 
      <div className="panel-body"> 
       <ul className="list-group"> 
       {this.ingredientList(item.ingredients)} 
       </ul> 
      </div> 
      </div> 
    ) 
    }, 

    add: function(text) { 
     var name = document.getElementById('name').value; 
     var items = document.getElementById('ingredients').value.split(","); 
     var arr = this.state.recipeList; 
     arr.push({ recipe: name, ingredients: items }); 
     this.setState({recipeList: arr}) 
    }, 

    render: function() { 
     return (
      <div> 
      <div> 
      <button type="button" className="btn btn-success btn-lg" data-toggle="modal" data-target="#myModal">Add Recipe</button> 
      <div id="myModal" className="modal fade" role="dialog"> 
      <div className="modal-dialog"> 

      <div className="modal-content"> 
      <div className="modal-header"> 
      <button type="button" className="close" data-dismiss="modal">&times;</button> 
      <h4 className="modal-title">Add a new recipe</h4> 
      </div> 
      <div className="modal-body"> 
      <form role="form"> 
        <div className="form-group"> 
         <label forName="recipeItems">Recipe</label> 
         <input ref="userVal" type="recipe" className="form-control" 
         id="name" placeholder="Enter Recipe Name"/> 
        </div> 
        <div className="form-group"> 
         <label for="ingredientItems">Ingredients</label> 
         <input ref="newIngredients" type="ingredients" className="form-control" 
          id="ingredients" placeholder="Enter Ingredients separated by commas"/> 
        </div> 
        <button onClick={this.add} type="submit" className="btn btn-default">Submit</button> 
        </form> 
      </div> 
      <div className="modal-footer"> 
      <button type="button" className="btn btn-default" data-dismiss="modal">Close</button> 
      </div> 
     </div> 
     </div> 
     </div> 
      { 
      this.state.recipeList.map(this.eachRecipe) 
      } 
      </div> 
      </div> 
     ); 
     } 
    }); 

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

回答

1

問題是,只要你點擊按鈕表單提交和頁面重新加載。

一種解決方案是將onClick={this.add}從按鈕中取出,並在<form>標記上添加onSubmit={this.add}代替。

所以,在add()功能你這樣做:

add: function(e) { 
    e.preventDefault(); 
    var form = e.target; 
    var name = form.name.value; 
    var items = form.ingredients.value.split(","); 
    var arr = this.state.recipeList; 
    arr.push({ recipe: name, ingredients: items }); 
    this.setState({recipeList: arr}); 
}, 

首先,你叫e.preventDefault()所以你的形式也不會重新加載頁面。其次,您可以使用target通過其屬性name訪問輸入值並設置狀態。

0

在代碼中可以改進的一些東西。

add: function(text) { 
    ... 
    arr.push({ recipe: name, ingredients: items }); 
    this.setState({recipeList: arr}) 
    } 

通過使用push()方法陣列上你基本上是修改通過推動新項目到它的組件的state。強烈建議您在不使用setState method的情況下直接改變React組件的狀態。

解決此問題的一種方法是創建一個新陣列,在該陣列中您將複製所有現有配方以及所添加的新配方。

如果您正在使用ES6/2015,它甚至easier來實現這一目標:

add: function(text) { 
    ... 
    var newRecipe = { 
    recipe: name, 
    ingredients: items 
    }; 
    this.setState({ recipeList: [...this.state.recipeList, newRecipe] }); 
} 

這樣,你不叫setState()方法從而保持它的完整之前修改組件的狀態。

下一頁

add: function() { 
    var name = document.getElementById('name').value; 
    var items = document.getElementById('ingredients').value.split(","); 
    ... 
} 

嘗試儘可能使用Refs(引用)來訪問你的輸入節點,這樣你就不必使用getElementById,因爲它更符合其餘的反應代碼。

add: function(text) { 
    var name = this.refs.userVal.value; 
    var items = this.refs.newIngredients.value.split(","); 
    ... 
}, 
render: function() { 
    return (
    <div> 
     ... 
     <input 
      ref="userVal" 
      placeholder="Enter Recipe Name" 
     /> 
     <input 
      ref="newIngredients" 
      placeholder="Enter Ingredients separated by commas" 
     /> 
     ... 
    </div> 
); 
}); 

最後一點

爲了防止Button元素提交表單,並帶你到另一個頁面,這就是發生在這裏,你可以在按鈕的type屬性設置爲button,它不應該再提交表格。 By default一個按鈕元素是submit類型。

<button onClick={this.add} type="button" className="btn btn-default">Submit</button> 

所以通過這樣做,你將不再需要「防止」的發生(這是提交表單),使用Event.preventDefault()方法在onClick功能處理器的默認操作。

這裏是一個jsBin鏈接與上述更改,你可以看看。

+0

非常感謝你,我明白你的方法和原因。我不敢相信這是一個簡單的解決方案! – Malekaii

相關問題