React JS - 获取单独的组件以在localStorage状态发生更改时重新渲染

问题描述:

我有两个组件。一个名为“GenerateRecipesFromList”的是一系列包含食谱标题的“框”,另一个是称为“AddButon”的子组件。现在,Add按钮可以更新localStorage,但为什么它不会“触发”父组件中的状态更改和重新呈现?React JS - 获取单独的组件以在localStorage状态发生更改时重新渲染

我CodePen这是here

var GenerateRecipesFromList= React.createClass({ 
    getInitialState: function(){ 
     const defaultData = [["Spaghetti", "pasta, oil, sauce, parsely, cheese"], ["PB&J", "PB, J"]] 
     const localData = JSON.parse(localStorage.getItem('reclist')); 
     return { 
     reclist: localData ? localData : defaultData 
     } 
    }, 
    render: function(){ 
    var testData = JSON.parse(localStorage.getItem('reclist')); 
    if(testData === null){ 
     localStorage.setItem('reclist', JSON.stringify(this.state.reclist)); 
     } 
     var currentData = JSON.parse(localStorage.getItem('reclist')); 
     var rows = []; 
      for(var i=0; i<currentData.length; i++){ 
     var thedivname = i; 
      rows.push(<div id= {this.thedivname} className="individual"> <span><h2>{this.state.reclist[i][0]}</h2></span> 
     </div>); 
     } 
     return(
     <div className="centerMe"> 
      <AddButton /> 
      {rows} 
     </div> 
    ); 
    }, 
}); 

var AddButton = React.createClass({ 

     overlayAdd: function() { 
     var el = document.getElementById("overlay"); 
     el.style.visibility = (el.style.visibility === "visible") ? "hidden" : "visible"; 
     }, 

     exposeAddRecipe: function(){ 
      var exposeCurrentData = []; 
      var userInput = []; 
      exposeCurrentData = JSON.parse(localStorage.getItem('reclist')); 
     var newTitle = document.getElementById("title").value; 
     var newIngredients = document.getElementById("ingredients").value; 

     userInput.push(newTitle); 
     userInput.push(newIngredients); 
     exposeCurrentData.push(userInput); 
      localStorage.setItem('reclist', JSON.stringify(exposeCurrentData)); 
      this.setState({ reclist: exposeCurrentData}); 
     this.overlayAdd(); 
     }, 

     render: function(){ 
     return(
     <div> 
      <button type="button" id="btnAdd" onClick={this.overlayAdd}>Add a New Recipe</button> 
      <div id="overlay"> 
      <div> 
      <form > 
      <p>Add a new recipe.</p> 
      Recipe Title: <input type="text" name="title" id="title" /><br/> 
      Ingredients: <input type="text" name="ingredients" id="ingredients" /><br/> 
      <button type="button" className="normalBtn" onClick={this.exposeAddRecipe}>Save</button> 
      </form> 
      <p>Click here to <a href='#' onClick={this.overlayAdd}>close</a></p> 

      </div> 
     </div> 
     </div> 
    ); 
    } 
    }); 

    var Footer = React.createClass({ 
    render() { 
    return (
     <footer> 
     <div id="containerfooter"> 
      <p>Written by <a href="http://codepen.io/profaneVoodoo/full/dXBJzN/">John Gillespie</a> for FreeCodeCamp Campers. Happy Coding!</p> 
    </div> 
     </footer> 
    ); 
    } 
    }); 


var MyApp = React.createClass({ 
    render: function() { 
    return(
     <div className = "mainDiv"> 
     <div className="titleDiv"> 
     <h1>Recipe Box</h1> 

      <GenerateRecipesFromList /> 
      <Footer /> 
     </div>   
     </div> 
    ); 
}, 
}); 

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

通过调用AddButton组件setState,你在更新这个组件,而不是父母的状态的状态。

要更新父级的状态,请在父级组件中定义一个函数,并将其传递到AddButton的道具中。然后你可以在AddButton中调用该函数来更新GenerateRecipesFromList的状态。

var GenerateRecipesFromList = React.createClass({ 
    // ... 
    updateRecList: function (reclist) { 
    this.setState({ reclist: reclist }); 
    }, 
    render: function(){ 
    // ... 
    return(
     <div className="centerMe"> 
     <AddButton updateRecList={ this.updateRecList } /> 
     { /* ... */ } 
     </div> 
    ); 
    }, 
}); 

var AddButton = React.createClass({ 
    // ... 
    exposeAddRecipe: function(){ 
    // ... 
    this.props.updateRecList(exposeCurrentData); 
    // ... 
    }, 
    // ... 
}); 

这是您的corrected code

+0

这是有道理的,我得到它的工作。谢谢! –