Is it possible to use React without rendering HTML?

I was wondering if it's possible to use React for doing logic and sending data back to a javascript function, without rendering any html. The component I'm thinking of is something that you pass some data to, and it'll send data back to a javascript function outside of react. I know that can be done, and I've done that part myself, but I'm not sure how you would do this without rendering html as it is required. Is this even a practical use case for react?


As of React >= 16.2 it is possible to use any of these versions:

render() { 
   return false; 
}

render() { 
   return null; 
}

render() { 
   return []; 
}

render() { 
   return <React.Fragment></React.Fragment>; 
}

render() { 
   return <></>; 
}

Returning undefined does not work.


The component I'm thinking of is something that you pass some data to, and it'll send data back to a javascript function outside of react.

Why would you want to create a component for that? Most of the time a regular js function in an existing component can be enough.

One usecase is for exemple to setup a side-effect when component is mounted and tear it down when it unmounts. For exemple if you have a ReactNative mobile app with portrait orientation, you could imagine a <Landscape/> component, that, when mounted, would allow temporarily to display the app in landscape orientation, and when unmounted, orientation would be reset to app default. You can surely manage this orientation change on an existing component, but creating a dedicated component might be more handy and reusable.

Note that React can also run on the server side so I guess it is possible to use it in such a way that it doesn't involve any DOM modifications (but maybe only the virtual DOM computation).


Just to clarify benno's comments. The ReactComponent.render method doc states:

You can also return null or false to indicate that you don't want anything rendered. Behind the scenes, React renders a <noscript> tag to work with our current diffing algorithm. When returning null or false, this.getDOMNode() will return null.


It is possible. react-router is an example of a library with components not rendering HTML. See https://github.com/rackt/react-router

This is the Route component of react-fouter with a render method returning false:


const Route = React.createClass({

  statics: {
    createRouteFromReactElement
  },

  propTypes: {
    path: string,
    component,
    components,
    getComponent: func,
    getComponents: func
  },

  /* istanbul ignore next: sanity check */
  render() {
    invariant(
      false,
      '<Route> elements are for router configuration only and should not be rendered'
    )
  }

})

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

Consider this example with react-router.

import React from 'react'
import { Route, Link } from 'react-router-dom'

function asyncComponent(getComponent) {
  return class AsyncComponent extends React.Component {
    static Component = null;
    state = { Component: AsyncComponent.Component };

    componentWillMount() {
      if (!this.state.Component) {
        getComponent().then(Component => {
          AsyncComponent.Component = Component
          this.setState({ Component })
        })
      }
    }
    render() {
      const { Component } = this.state
      if (Component) {
        return <Component {...this.props} />
      }
      return null
    }
  }
}

const Page1 = asyncComponent(() =>
  System.import('./Page1.js').then(module => module.default)
)
const Page2 = asyncComponent(() =>
  System.import('./Page2.js').then(module => module.default)
)
const Page3 = asyncComponent(() =>
  System.import('./Page3.js').then(module => module.default)
)

const ParentComponent = () => (
  <div>
    <ul>
      <li>
      <Link to="/page1">Page1</Link>
      </li>
      <li>
      <Link to="/page2">Page2</Link>
      </li>
      <li>
      <Link to="/page3">Page3</Link>
      </li>
    </ul>
    <div>
      <Route path="/page1" component={Page1}/>
      <Route path="/page2" component={Page2}/>
      <Route path="/page3" component={Page3}/>
    </div>
  </div>
)