如何更改其他组件的状态?

时间:2017-04-17 14:50:53

标签: javascript reactjs state

CODE:

var React = require('react');
var RecipeBox = require('./RecipeBox.jsx');
var AddRecipe = React.createClass({
    handleClick: function () {
         RecipeBox.setState({
             adding: false
         });
    },
    render: function() {
        return (
            <div className="popUp">
                <button className = "btn btn-danger" onClick={this.handleClick}>X</button>
                <h2>Add a Recipe</h2>
                <form>
                    <h3>Name</h3>
                    <input></input>
                    <h3>Ingredients</h3>
                    <textarea></textarea>
                    <button type="submit" className="btn btn-success">Submit</button>
                </form>
            </div>
        );
    }
});

module.exports = AddRecipe;

状况:

上述解决方案不起作用。我想从AddRecipe组件为RecipeBox组件设置addingfalse

3 个答案:

答案 0 :(得分:1)

你不能那样做,请看这里how to communicate between components。 您必须使用父/子组件来执行此操作,或使用类似Redux

的库

答案 1 :(得分:0)

您不应该直接从父级更改子组件状态,因为这不是首选的React方式。您可以将adding作为prop传递给RecipeBox组件,并在componentWillReceiveProps组件中设置RecipeBox方法,以设置RecipeBox状态。

如果由于某种原因确实需要(直接),您可以在ref组件上添加RecipeBox,如下所示:

<RecipeBox ref={(ref) => this.recipeBox = ref} adding={this.state.adding}/>

而且您可以从this.recipeBox.setState({...})组件中调用AddRecipe。但请记住,这不是首选的反应方式。

答案 2 :(得分:-1)

如果AddRecipe与RecipeBox无关

然后你可以像microevent这样的小型库使用像这样的观察者模式:

在一些名为events.js的模块中,例如:

var MicroEvent = require('./microevent.js');
module.exports = new Ticker();

在RecipeBox的文件中:

var ticker = require('./events.js');

var RecipeBox = React.createClass({

  componentDidMount: function() {
    this.addingHandler = () => this.setState({ adding: false });
    ticker.bind('adding', this.addingHandler);
  },

  componentWillUnmount: function() {
    ticker.unbind('adding', this.addingHandler);
  }

});

在AddRecipe的文件中:

var React = require('react');
var RecipeBox = require('./RecipeBox.jsx');
var ticker = require('./events.js');

var AddRecipe = React.createClass({
    onAdd: function() {
      ticker.trigger('adding');
    },
    render: function() {
        return (
            <div className="popUp">
                <button className = "btn btn-danger" onClick={this.onAdd}>X</button>
                <h2>Add a Recipe</h2>
                <form>
                    <h3>Name</h3>
                    <input></input>
                    <h3>Ingredients</h3>
                    <textarea></textarea>
                    <button type="submit" className="btn btn-success">Submit</button>
                </form>
            </div>
        );
    }
});

module.exports = AddRecipe;

如果RecipeBox是AddRecipe的孩子

您不应该尝试以这种方式更改RecipeBox的状态。如果RecipeBoxAddRecipe的子组件,那么您应该将支柱传递给它:

var React = require('react');
var RecipeBox = require('./RecipeBox.jsx');
var AddRecipe = React.createClass({
    handleClick: function () {
         // you should only change your own state, see how
         // we set 'adding' on RecipeBox on one of the last
         // lines of render instead
         this.setState({
             adding: false
         });
    },
    render: function() {
        return (
            <div className="popUp">
                <button className = "btn btn-danger" onClick={this.handleClick}>X</button>
                <h2>Add a Recipe</h2>
                <form>
                    <h3>Name</h3>
                    <input></input>
                    <h3>Ingredients</h3>
                    <textarea></textarea>
                    <button type="submit" className="btn btn-success">Submit</button>
                </form>
                <RecipeBox adding={this.state.adding}/>
            </div>
        );
    }
});

module.exports = AddRecipe;

如果AddRecipe是RecipeBox的孩子

如果RecipeBoxAddRecipe的父级,那么您应该将adding: false传播到RecipeBox,如下所示:

var RecipeBox = React.createClass({

  render: function() {
    return <AddRecipe onAdd={this.onAdd.bind(this}/>;
  }

  onAdd: function() {
    this.setState({ adding: false });
  }

});

var React = require('react');
var RecipeBox = require('./RecipeBox.jsx');
var AddRecipe = React.createClass({
    render: function() {
        return (
            <div className="popUp">
                <button className = "btn btn-danger" onClick={this.props.onAdd}>X</button>
                <h2>Add a Recipe</h2>
                <form>
                    <h3>Name</h3>
                    <input></input>
                    <h3>Ingredients</h3>
                    <textarea></textarea>
                    <button type="submit" className="btn btn-success">Submit</button>
                </form>
            </div>
        );
    }
});

module.exports = AddRecipe;