简体   繁体   中英

How to delay evaluation of JSX passed as props children to another component?

React 16.13 . I'm writing a Loader component to handle different failure states and passing the "successful" content as a child like this:

<Loader
    isLoading={loading}
    isError={error}>

    <div>{this.props.loadedContentFromRedux}</div>
</Loader>

The Loader component is quite simple:

class Loader extends Component {

render() {
    return this.props.isLoading ? <Spinner /> :
    this.props.isError ? <Error /> :
    this.props.children
}

}

As I understand, because I am passing the loadedContentFromRedux props to the child directly, it is being evaluated before passed as a child to Loader and therefore evaluating it prior to the Loader 's render method called.

Is there a way I can delay evaluation to prevent this or do I need to guard against it? Or perhaps clone the child and pass the props that way?

Try this:

const loadedContent = () => <div>{this.props.loadedContentFromRedux}</div>

<Loader
 isLoading={loading}
 isError={error}
 loadedContent={loadedContent}       
/>

Change the Loader component to:

class Loader extends Component {

render() {
    return this.props.isLoading ? <Spinner /> :
    this.props.isError ? <Error /> :
    this.props.loadedContent()
   }
}

By doing this you r not executing the loadedContent while passing, so that this.props.loadedContentFromRedux execution will not happen. It will execute in Loader component in render method.

Edited Answer

I was able to build upon this and change the syntax a bit so it is easier on the eyes and pass the function as a child. It requires a type check in the Loader render as such:

<Loader
 isLoading={loading}
 isError={error}>

{() => <div>{this.props.loadedContentFromRedux}</div>}

</Loader>

Then guard against a function type as follows - this is because the JSX is sometimes prematurely evaluated:

class Loader extends Component {

render() {
    return this.props.isLoading ? <Spinner /> :
    this.props.isError ? <Error /> :
    typeof this.props.children==='function' ? this.props.children() :
    this.props.children
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM