簡體   English   中英

React子組件props:_this2.props.delete不是函數

[英]React child component props : _this2.props.deleteIt is not a function

嘗試創建食譜盒時,我希望您的見解。

https://codepen.io/gianndall/pen/evyBYd?editors=0010

class RecipeList extends React.Component {

  constructor(props) {
    super(props); 
    this.state = {
    }
  }

  render() { 
        var list = JSON.parse(this.props.recipes);
  console.log (list);
    return (      
      <ul className="collection">
        {list.map( (x) => 
                  <li className="collection-item">
                    <div>
                      {x.name} {list.indexOf(x)}                      
                      <a href="#!" className="secondary-content">
                        <i className="material-icons"
                          onClick = {() => this.props.deleteIt(list.indexOf(x))}
                          >delete</i></a>
                      <a href="#!" className="secondary-content"><i className="material-icons">edit</i></a>
                    </div>
                  </li> )}
      </ul>
    )
  }
}

class AddRecipeModal extends React.Component {

    constructor(props) {
    super(props);
    this.state = {
      input1: '',
      textarea1: ''
    }
  }    

  handleChangeTextarea(event) {
    this.setState({textarea1: event.target.value});
  }
  handleChangeInput(event) {
    this.setState({input1: event.target.value});
  }

  handleSubmit(event) {
    alert('A recipe was submitted: ' + this.state.input1 + ' '+ this.state.textarea1);
    event.preventDefault();
     if(typeof(Storage) !== "undefined") {

    console.log(localStorage.Recipes);

    if (localStorage.Recipes){

      var newRecipe = this.state.input1;
      var newIngredient = this.state.textarea1.split(',');
      console.log( 'vers 2' , newRecipe);
      var x = JSON.parse( localStorage.Recipes );
      console.log('vers 2' , x);
      x.push(
        {name:newRecipe,
         contans: newIngredient
        }
      );
      var updated = localStorage
      .setItem('Recipes',JSON.stringify(x));

    }else{
      var i=[];
      var newRecipe = this.state.input1;
      var newIngredient = this.state.textarea1.split(',');
      i.push(
        {name:newRecipe,
         contans: newIngredient
        }
      );
      localStorage
      .setItem('Recipes',JSON.stringify(i));
      console.log('vers 1 i= ',i);
      console.log('vers1 RECIPES ', localStorage.Recipes);      
    }

  }else{
        alert("Sorry, your browser does not support web storage...");
    }
  console.log('test');
    {this.props.closeIt()}
  }

  render() {
    return(

    <div id="modal1" className= {'modal ' + (this.props.display ? 'open' : '') }>
        <div className="modal-content">
          <h4>Add Recipe</h4>
          <form onSubmit={this.handleSubmit.bind(this)} >
          <div className="input-field" >
            <input id="input1" type="text" value={this.state.input1} onChange={this.handleChangeInput.bind(this)} />
            <label for="first_name">Recipe Name</label>
          </div>

          <div className="input-field" >
          <textarea id="textarea1" className="materialize-textarea" value={this.state.textarea1} onChange={this.handleChangeTextarea.bind(this)} />
          <label for="textarea1">Ingredient - separate with comma:</label>
          </div>
            <button type="Submit" className="waves-effect waves-light btn"><i className="material-icons left">add</i>Add it</button>
          </form>
        </div>
        <div className="modal-footer">
          <a href="#!" className="modal-action modal-close waves-effect waves-green btn-flat" onClick={this.props.closeIt}>Cancel</a>
        </div>
      </div>
      )
  }

}

class RecipesBox extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      modalShow: false
    }
  }  

  openModal(){
    this.setState({
      modalShow: true
    })
  }

  closeModal(){
    this.setState({
      modalShow: false
    })
  }

  deleteRecipe(x) {
    console.log('test', x);
    var list = JSON.parse(localStorage.Recipes);
    list.splice(x,1);
    console.log('list =',list);
    localStorage.Recipes = JSON.stringify(list);
  };


  render() {

    const listed = localStorage.Recipes ?
        <RecipeList recipes={localStorage.Recipes} deletIt={this.deleteRecipe}/> :
        <ul className="collection"><li className="collection-item">The Recipe Box is empty</li>
      </ul> 

      return (      
      <div>
        <nav className="nav-extended">
          <div className="nav-content">
            <span className="nav-title">Recipe Box</span>
            <a className="btn-floating btn-large halfway-fab waves-effect waves-light teal" onClick={this.openModal.bind(this)}>
              <i className="material-icons">add</i>
            </a>
          </div>
        </nav>
        {listed}
        < AddRecipeModal display={this.state.modalShow} closeIt ={this.closeModal.bind(this)}/>


   </div>      
    )    
  }
}

class newRecipe extends React.Component {}

ReactDOM.render(
  < RecipesBox />,
  document.getElementById('app')
);

經過幾天的閱讀和沮喪,我無法刪除列表項。 我在創建帶有參數的props函數時遇到問題,該函數將值從子級傳遞到父級(特別是本地存儲數組索引)。

我不斷收到_this2.props.deleteIt is not a function錯誤

我當然可以創建一個龐大的組件並使我的生活更輕松,但這不是重點。 我想學習如何處理較小的組件

我真的希望您能對此有所了解。

謝謝

您必須將其作為deleteIt而不是deletIt

<RecipeList deletIt={this.deleteRecipe} />

應該

<RecipeList deleteIt={this.deleteRecipe} />

另外,將來您可能需要在deleteRecipe方法中引用this方法。 因此,此時您可能需要使用箭頭功能或.bind

好吧,看來您輸入了錯誤的內容:

<RecipeList recipes={localStorage.Recipes} deletIt={this.deleteRecipe}/> :

應該是這樣的:

<RecipeList recipes={localStorage.Recipes} deleteIt={this.deleteRecipe}/> :

由於您的組件不會在刪除時觸發渲染,因此我建議您3個選擇:

  • 將配方存儲在主要組件狀態中以處理組件渲染。
  • 在您的主要組件中添加一個localStorage偵聽器。
  • 使用商店提供商(例如redux)

編輯:嘗試避免從官方文檔中使用forceUpdate():

通常,您應該避免使用forceUpdate(),而只能從render()中的this.props和this.state中讀取。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM