Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/423.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 当React JS中的父状态更改时,如何在子级中更改this.props?_Javascript_Reactjs - Fatal编程技术网

Javascript 当React JS中的父状态更改时,如何在子级中更改this.props?

Javascript 当React JS中的父状态更改时,如何在子级中更改this.props?,javascript,reactjs,Javascript,Reactjs,新的反应JS在这里。我有一个设置,其中我有一个应用程序父组件,它有一个initialFormInput状态,保存一个配方对象。将函数从父组件传递到名为EditRecipeButton的子组件,该子组件可以将此状态更改为从编辑按钮调用的特定配方 父组件中的此状态通过via This.props映射到子AddRecipe组件中的状态,我的推理是,每当父组件状态更改时,AddRecipe中的此状态也会更改。但那没有发生,我做错了什么 这是我的密码: var App = React.createClas

新的反应JS在这里。我有一个设置,其中我有一个应用程序父组件,它有一个initialFormInput状态,保存一个配方对象。将函数从父组件传递到名为EditRecipeButton的子组件,该子组件可以将此状态更改为从编辑按钮调用的特定配方

父组件中的此状态通过via This.props映射到子AddRecipe组件中的状态,我的推理是,每当父组件状态更改时,AddRecipe中的此状态也会更改。但那没有发生,我做错了什么

这是我的密码:

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'));

});

如果您想在组件之间共享状态,请使用redux isntead。还为每个组件维护一个单独的文件。 此链接可能对您有所帮助

如果要跨组件共享状态,请使用redux isntead。还为每个组件维护一个单独的文件。 此链接可能对您有所帮助

顾名思义,
getInitialState
只提供组件的初始状态。后续更新不会触发该函数

您需要实现
组件将接收道具
,以便在道具更改时更新状态。从:

componentWillReceiveProps()
在安装的组件接收新的道具之前被调用。如果需要更新状态以响应道具更改(例如,重置它),可以比较
this.props
nextrops
,并在此方法中使用
this.setState()
执行状态转换

请注意,即使道具没有更改,React也可能调用此方法,因此如果您只想处理更改,请确保比较当前值和下一个值。当父组件导致组件重新渲染时,可能会发生这种情况


顾名思义,
getInitialState
只提供组件的初始状态。后续更新不会触发该函数

您需要实现
组件将接收道具
,以便在道具更改时更新状态。从:

componentWillReceiveProps()
在安装的组件接收新的道具之前被调用。如果需要更新状态以响应道具更改(例如,重置它),可以比较
this.props
nextrops
,并在此方法中使用
this.setState()
执行状态转换

请注意,即使道具没有更改,React也可能调用此方法,因此如果您只想处理更改,请确保比较当前值和下一个值。当父组件导致组件重新渲染时,可能会发生这种情况


您需要实现(或者不在子组件中保持状态)。一般来说,您可能也会对此感兴趣:。您需要实现(或者不在子组件中保留状态)。一般来说,您可能也会对此感兴趣:。但没有理由将样板文件添加到简单应用程序中。但也没有理由将样板文件添加到简单应用程序中。
getInitialState(){

    return {

     name: this.props.initialFormInput.name, 

     ingredients: this.props.initialFormInput.ingredients


    };

  },