Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Router v4 - Pre-Mount Component Without Rendering

I have a component that takes a while to load. Actually, it's a component which loads an <iframe> of another website, which takes a while to load.

I would like the component to mount and therefore run the componentDidMount code block that loads the iframe so that when the user clicks on the 'create' tab, the user instantly sees the iframe in the correct the <main> section of the page.

Is there a way to instruct react-router to pre-load the component while retaining the same conditional rendering logic on route change and retaining the position on the page of the rendered component?

This is currently my render() statement on the root level of the app to give you some context:

render() {
  return (
    <div className="App">
      <Nav />
      <Snackbar
        open={this.props.snackbar.get().open}
        message={this.props.snackbar.get().message}
        autoHideDuration={4000}
        onRequestClose={() => this.handleSnackbarRequestClose()}
      />
      <TreeViewer />
      <PayloadListener/>
      <main>
        <ThankYouModal open={this.props.showConfirmationModal.get()} handleClose={ () => this.props.showConfirmationModal.set(false) }/>
        <Switch>
          <Route path="/imageservices" component={ImageServicesController} />
          <Route path="/create"        component={Iframe} />
          <Route exact path="/account" component={Account} />
          <Route exact path="/analytics" component={AnalyticsController} />
          <Route path="/support"       component={SupportView} />
          <Route path='/login'         render={ (props) => <Login { ...props } /> } />
          <Route path='/logout'        render={ (props) => <Logout { ...props } /> } />
        </Switch>
      </main>
    </div>
  );
}

This is the component I would like React Router to pre-load:

<Route path="/create" component={Iframe} />

How can I achieve that?

like image 391
maxwell Avatar asked May 31 '17 22:05

maxwell


People also ask

Does every React component need a render?

React components don't have to render anything.

How can you prevent re rendering a total component if it hasn't changed?

1. Memoization using useMemo() and UseCallback() Hooks. Memoization enables your code to re-render components only if there's a change in the props. With this technique, developers can avoid unnecessary renderings and reduce the computational load in applications.

Is it possible to use React without rendering HTML?

Yes it is very much possible and very much useful, in case of lazy loading components.

Why does a component requires a render () method?

Purpose of render(): The purpose of the function is to display the specified HTML code inside the specified HTML element. In the render() method, we can read props and state and return our JSX code to the root component of our app.


1 Answers

Well if you take a look at a React component lifecycle you can see that render always runs before componentDidMount. So effectively you wouldn't be able to mount a component without rendering it.

These are the lifecycle methods called while mounting:

  • constructor()
  • static getDerivedStateFromProps()
  • render()
  • componentDidMount()

You can try a few things:

  • Render the iframe when you need it and fade it in when it is loaded.

You can easily add an eventListener for the load event of the iframe and make the appropriate changes for it to fadeIn when the state changes.

...
componentDidMount() {
  this.iframe.addEventListener("load", this.handleLoad);
}

componentWillUnmout() {
  this.iframe.removeEventListener("load", this.handleLoad);
}
...
<iframe ref={ref => this.iframe = ref } />
...

I've done this when I didn't always need the iframe. It was something sporadic and it was an always one page kinda thing.

  • You can play around with the preload attribute

This is ideal if you know the user will stumble upon the iframe content. You can start preloading content that the user will most likely encounter effectively preventing the user from waiting.

You can add this to the head of your document:

<link rel="preload" href="your-doc-url" as="document" />

And then use your iframe normally:

<iframe src="your-doc-url"></iframe>

If your iframe url is dynamic and dependent on some info from the authenticated user and you can't put it right away in your html file remember you can always use react-helmet to render it to the head tag whenever you have the info you want.

like image 122
João Cunha Avatar answered Oct 24 '22 16:10

João Cunha