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
};
},
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. –