Jason Chen
Jason Chen

Reputation: 2577

Call multiple functions in React, one inside and another outside a component?

I have a trigger that is supposed to change a state of its child component. The results of both render statements are inconsequential. My only concern here is that I am unsure how to use the trigger trigger to call the leftbehind function without putting leftbehind inside its parent render Another.

My code is below. The goal is to have leftbehind run without having to put it inside the render.

var Another = React.createClass({
  leftbehind: function() {
    if (this.props.status === "dare") {
      alert('Winning!');
    }
  },
  render: function() {
    if (this.props.status === "truth") {
      return (<p>Yes</p>);
    } else {
      return (<p>Nope</p>);
    }
  }
});

var App = React.createClass({
  getInitialState:function() {
    return {deesfault: "truth"};
  },
  trigger: function() {
    this.setState({deesfault: "dare"});
  },
  render: function() {
    return (
      <div> 
        <p onClick={this.trigger}>{this.state.deesfault}</p>
        <Another status={this.state.deesfault}/>
      </div>
    );
  }
});

The reason I do not want to place leftbehind inside the render, is because it is technically supposed to take the place of an API call. And I do not want that to be called inside the render function.

Upvotes: 1

Views: 1805

Answers (1)

Season
Season

Reputation: 4376

Your implementation executes leftbehind each time <Another> is rendering with its status prop being true. That said, once status is flipped to true, leftbehind will be executed over and over in every following rendering until it is flipped back to false. This will seriously cause problems.

Since the intention is to trigger leftbehind with a click event, I would restructure the components in different ways.

  • Move leftbehind into the parent component and have it executed along with the click event. If <Another> needs the results, passed them on through props.

    var Another = React.createClass({
      render() {
        return <div>{this.props.params}</div>;
      }
    });
    
    var App = React.createClass({
      getInitialState() {
        return {apiRes: null};
      },
      onClick() {
        const res = someAPICall();
        this.setState({apiRes: res});
      },
      render() {
        return (
          <div>
            <p onClick={this.onClick}>Fire</p>
            <Another params={this.state.apiRes} />
          </div>
        );
      }
    });
    
  • Or, move the <p> element into <Another> along with the click event.

    var Another = React.createClass({
      getInitialState() {
        return {apiRes: null};
      },
      onClick() {
        var res = someAPICall();
        this.setState({apiRes: res});
      },
      render() {
        return (
          <div>
            <p onClick={this.onClick}>Fire</p>
            <div>{this.state.apiRes}</div>
          </div>
        );
      }
    });
    
    var App = function() { return <Another />; }
    

In the latter, the key logic is handled in the inner component. The outer one is just a container. In the former one, the outer component handles the logic and pass on the results if any. It depends on how the components relate with the API call to decide which suits better. Most importantly, in both cases the API will not execute unless the click event is triggered.

Upvotes: 1

Related Questions