2016-12-14 3 views
0

neu zu Reagieren JS hier. Ich habe ein Setup, wo ich eine App Elternkomponente, die eine initialFormInput Zustand hält ein Rezept-Objekt hat. Eine Funktion wird von der übergeordneten Komponente an eine untergeordnete Komponente mit der Bezeichnung EditRecipeButton übergeben, die diesen Status in ein bestimmtes Rezept ändern kann, das über eine Bearbeitungsschaltfläche aufgerufen wird.Wie ändert man this.props im Kind, wenn sich der Elternstatus in React JS ändert?

Dieser Status im Eltern wird einem Zustand in einer untergeordneten AddRecipe-Komponente mit einem via this.props zugeordnet, und meine Argumentation ist, dass, wenn der Elternkomponentenstatus ändert sich dieser Status in AddRecipe auch ändert. Aber das passiert nicht, was mache ich hier falsch?

Hier ist mein Code:

var App = React.createClass({ 


    getInitialState(){ 

    return{ 

     showModal:false, 


     recipeKeys: [ ], 

     recipes: [ ], 

     initialFormInput: {name: "", ingredients: []} 

    } 


    }, 


    open: function(){ 


    this.setState({showModal:true}); 

    }, 

    close: function(){ 

    this.setState({showModal:false}); 

    }, 

    editRecipe: function(recipe){ 

    console.log(recipe); 

    this.setState({initialFormInput: recipe}, function(){ 

     this.open(); 


    }); 


    }, 

    render: function(){ 

    return( 

     <div className="container"> 
     <h1>Recipe Box</h1> 
     <RecipeList recipes = {this.state.recipes} deleteRecipe = {this.deleteRecipe} editRecipe={this.editRecipe} /> 
     <AddRecipeButton openModal = {this.open}/> 
     <AddRecipe closeModal = {this.close} showModal={this.state.showModal} addRecipeKey = {this.addRecipeKey} initialFormInput = {this.state.initialFormInput}/> 
     </div> 

    ) 

    } 


var RecipeList = function (props) { 

    return (
     <ul className="list-group"> 
      { 

      props.recipes.map((item,index) => <RecipeItem recipe={item} deleteRecipe = {props.deleteRecipe} editRecipe={props.editRecipe}/>) 

      } 
     </ul> 
    ); 
}; 

var RecipeItem = React.createClass({ 

getInitialState: function(){ 

    return {displayIngredients: false} 

}, 

toggleRecipe: function() { 

    this.setState({displayIngredients: !this.state.displayIngredients}) 

}, 

render: function() { 

    return(

     <li className="list-group-item" > 
     <h4 onClick={this.toggleRecipe}>{this.props.recipe.name}</h4> 
     <div style={{display: this.state.displayIngredients ? 'block' : 'none'}}> 
     <h5 className="text-center">Ingredients</h5> 
     <hr/> 
     <ul className="list-group" > 
     {this.props.recipe.ingredients.map((item) => <IngredientItem ingredient={item} />)} 
     </ul> 
     <ButtonToolbar> 
     <DeleteRecipeButton deleteRecipe = {this.props.deleteRecipe} recipeName={this.props.recipe.name}/> 
     <EditRecipeButton editRecipe = {this.props.editRecipe} recipe={this.props.recipe}/> 
     </ButtonToolbar> 
     </div> 
     </li> 


    ) 


} 

}); 

var IngredientItem = function(props){ 

    return (
    <li className="list-group-item"> 

    <p>{props.ingredient}</p> 
    </li> 


) 

}; 


var EditRecipeButton = React.createClass({ 

    render: function(){ 

    return (

    <Button bsStyle="default" bsSize="small" onClick={() => this.props.editRecipe(this.props.recipe)}>Edit</Button> 

    ) 

    } 


}); 


var AddRecipe = React.createClass({ 
//Form in modal to add recipe 

    getInitialState(){ 

    return { 

    name: this.props.initialFormInput.name, 

    ingredients: this.props.initialFormInput.ingredients 


    }; 

    }, 


    getValidationStateName(){ 

    var length = this.state.name.length; 

    if(length > 0) { 

     return "success"; 

    } else { 

     return "error"; 

    } 

    }, 

    getValidationStateIngredients(){ 

    var length = this.state.ingredients.length; 

    if(length > 0){ 

     return "success"; 

    } else { 

     return "error"; 

    } 


    }, 

    handleInput: function(key,e){ 

    var input = e.target.value; 


    if(key === "ingredients"){ 

     input = e.target.value.split(","); 

    } 

    var update = {}; 

    update[key] = input; 

    this.setState(update, function(){ 

     console.log(this.state); 

    }); 


    }, 

handleSubmit(){ 

    var recipe = JSON.stringify({name: this.state.name, ingredients: this.state.ingredients}); 

    localStorage.setItem(this.state.name, recipe); 

    var recipeObject= JSON.parse(recipe); 

    this.props.addRecipeKey(recipeObject); 

    this.props.closeModal(); 

    this.setState({name: "", ingredients: []}); 


    }, 

    render: function(){ 

    return (

     <div> 
     <Modal show={this.props.showModal} onHide={this.props.closeModal}> 
      <Modal.Header closeButton> 
       <Modal.Title>Add a Recipe Here</Modal.Title> 
      </Modal.Header> 
      <Modal.Body> 
       <form> 
     <FormGroup controlId="formNameText" validationState = {this.getValidationStateName()}> 
      <ControlLabel>Recipe</ControlLabel> 
      <FormControl 
      type="text" 
      placeholder="Give your recipe a name" 
      value={this.state.name} 
      onInput={this.handleInput.bind(this,'name')} 
      /> 
      <FormControl.Feedback /> 
     </FormGroup> 
      <br/> 
     <FormGroup controlId="formIngredientsTextarea" validationState = {this.getValidationStateIngredients()}> 
      <ControlLabel>Ingredients</ControlLabel> 
      <FormControl 
      componentClass="textarea" 
      placeholder="Insert your ingredients, separated by a comma" 
      value={this.state.ingredients} 
      onInput={this.handleInput.bind(this,'ingredients')} 
      /> 
      <FormControl.Feedback /> 
      <hr/> 
     </FormGroup> 

     <Button bsStyle="primary" onClick={this.handleSubmit}>Submit</Button> 
     </form> 
      </Modal.Body> 
     </Modal> 
     </div> 


    ) 
    } 

}); 


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

}); 

So bedeutet dies nicht ändern, wenn die Eltern Zustandsänderungen:

getInitialState(){ 

    return { 

    name: this.props.initialFormInput.name, 

    ingredients: this.props.initialFormInput.ingredients 


    }; 

    }, 
+1

Sie müssen https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops implementieren (oder den Status in der untergeordneten Komponente nicht beibehalten). Das könnte Sie auch im Allgemeinen interessieren: https://facebook.github.io/react/docs/state-and-lifecycle.html. –

Antwort

0

Wenn Sie Zustand teilen möchten über Komponenten redux isntead verwenden. Pflegen Sie auch eine separate Datei für jede Komponente. Dieser Link könnte Ihnen helfen Step by Step Guide To Building React Redux Apps

+1

Es gibt keinen Grund, einfache Anwendungen zu einfachen Apps hinzuzufügen. –

2

Wie der Name schon sagt, bietet getInitialState nur die anfänglichen Zustand einer Komponente. Nachfolgendes Update wird diese Funktion nicht auslösen.

Sie müssen componentWillReceiveProps implementieren, um den Status zu aktualisieren, wenn sich die Requisiten ändern. Vom docs:

componentWillReceiveProps() wird aufgerufen, bevor ein montiertes Bauteil neue Requisiten erhält. Wenn Sie den Status als Antwort auf Prop-Änderungen aktualisieren müssen (z. B. um ihn zurückzusetzen), können Sie this.props und nextProps vergleichen und Zustandsübergänge mit this.setState() in dieser Methode durchführen.

Beachten Sie, dass React diese Methode auch dann aufrufen kann, wenn sich die Requisiten nicht geändert haben. Vergleichen Sie daher den aktuellen und den nächsten Wert, wenn Sie nur Änderungen bearbeiten möchten. Dies kann auftreten, wenn die Komponente die Komponente erneut rendern lässt.

Verwandte Themen