Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why react calls function in subcomponents event when this subsomponents not rendered?

Here is the example

const getResult = () => {
  document.getElementById('logger').innerHTML += "FUNCTION CALLs immediately";
  return 'RESULT string AFTER 3S';
}

const A = () => {
  return (
    <Wrapper>
      {getResult()}
    </Wrapper>
  );
};

class Wrapper extends React.Component {
  constructor() {
    super();
    this.state = { active: false }
  }

  componentDidMount() {
    setTimeout(() => this.setState({ active: true }), 3000);
  }

  render() {
    return (
      <div>
        {this.state.active && this.props.children}
      </div>
    );
  }
}

ReactDOM.render(<A />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="logger"></div>
<div id="app"></div>

The question is - why getResult function calls immediately? children component in Wrapper should be rendered after 3s. But function calls immediately anyway. Why is so?

like image 227
Slava Avatar asked Nov 07 '22 11:11

Slava


1 Answers

Technically you invoking function and React treats a result of this function as children - RESULT string AFTER 3S. If would like to delay the function invocation you can invoke in when the state is changed.

const getResult = () => {
  document.getElementById('logger').innerHTML += "FUNCTION CALLs immediately";
  return 'RESULT string AFTER 3S';
}

const A = () => {
  return (
    <Wrapper>
      {getResult} // remove immediate invocation
    </Wrapper>
  );
};

class Wrapper extends React.Component {
  ...

  render() {
    return (
      <div>
        // here we can invoke children as a function, because we pass a function
        {this.state.active && this.props.children()}
      </div>
    );
  }
}

Then you'll get expected result. Worked example

like image 149
The Reason Avatar answered Nov 14 '22 22:11

The Reason