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')
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:
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')
)
)()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With