Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React.createElement - converting jsx to normal function calls on a large scale

How should I convert jsx libraries and elements to normal function calls? Is there any difference between the following two code samples (example simple app component with react-router components is just an example, could be anything, or any element types like 'div', or 'p', or other jsx library):

// normal jsx
const PublicApp = () => (
  <Switch>
    <Route path="/register" component={Register} />
    <Route path="/login" component={Login} />
    <Route path="/about" component={About} />
    <Redirect to="/login" />
  </Switch>
)
// desired api
const PublicApp = () =>
  Switch(
    {},
    Route({ path: '/register', component: Register }),
    Route({ path: '/login', component: Login }),
    Route({ path: '/about', component: About }),
    Redirect({ to: '/login' })
  )
// required helpers
import { createElement as h } from 'react'
import * as ReactRouter from 'react-router'

export const Switch = (props, ...children) =>
  h(ReactRouter.Switch, props, ...children)

export const Route = (props, ...children) =>
  h(ReactRouter.Route, props, ...children)

export const Redirect = (props, ...children) =>
  h(ReactRouter.Redirect, props, ...children)

export const Div = (props, ...children) => h('div', props, ...children)

. . . .

Both seem to work fine. Any problem with doing this on a large scale? Also, seems sort of silly to have to manually wrap every element type. Is there a better way than using a converter like this:

const converter = el => (props, ...children) => h(el, props, ...children)

export const Switch = converter(ReactRouter.Switch)

export const Route = converter(ReactRouter.Route)

export const Redirect = converter(ReactRouter.Redirect)

export const Div = converter('div')
like image 319
RichardForrester Avatar asked Aug 05 '26 22:08

RichardForrester


1 Answers

After some searching, it appears that njsx has the best and most well thought out api.

Third-party library components can be individually wrapped in the nsjx default export.

You can even do point-free rendering (tested with ramda.compose):

<Provider store={store}>
  <PersistGate loading={null} persistor={persistor}>
    <BrowserRouter>
      <Route path="/" component={App} />
    </BrowserRouter>
  </PersistGate>
</Provider>

becomes:

compose(
  Provider({ store }),
  PersistGate({ loading: null, persistor }),
  BrowserRouter,
  Route
)({ path: '/', component: App })()

From the docs:

No-JSX

A pure function based interface for creating React and React Native components without JSX tags.

If you love React but don't quite like the embeded HTML tags this library may be what you are looking for. Construct your components with code only in a clean, declarative way.

const myView = () =>
  div.app(
    div.header(
      img({src: logo, alt:'logo'}),
      h2('Welcome to NJSX')
    )
  )()
like image 90
RichardForrester Avatar answered Aug 08 '26 11:08

RichardForrester



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!