Render React components inside your ember templates:
✅ Supports nested React components and composition
✅ Supports React Context
✅ Low runtime footprint: XReact components are transformed into react components at build time !
✅ Use ember and react features together: Conditional components in a {{#if}} block, pass @tracked properties in props
✅ Supports DOM elements as children
✅ Props type safety in the template
❌ You cannot use the yield keyword inside a XReact component
❌ You cannot have ember components inside XReact components
- Ember.js v4.12 or above
- Embroider or ember-auto-import v2
ember install ember-x-react Most of the transformation logic is made at build time via a babel plugin; Add the plugin in your ember-cli-build.js configuration:
new EmberApp(defaults, { babel: { plugins: [ // ... require('ember-x-react').buildBabelPlugin(), ], }, });or directly in your Babel config file if you enabled useBabelConfig: true
if your app is using embroider with webpack, you need to tell webpack how to handle JSX:
rules: [ // ... { test: /\.jsx/, // replace or add tsx if you use typescript use: { loader: 'babel-loader', options: { presets: [ // Add other presets here if you need Typescript support for example ['@babel/preset-react', { runtime: 'automatic' }], ], }, }, }, ];import XReactRoot from 'ember-x-react/components/x-react/root'; import XReact from 'ember-x-react/components/x-react'; import MyButton from './my-button.tsx'; export default class MyForm extends Component { ... get isFormPending() { return this.submitTask.isPending; } <template> <form> <MyEmberDropdown /> <XReact::Root> <XReact @component={{MyButton}} @props={{hash isPending=this.isFormPending}}> {{#if this.isFormPending}} Submitting ... {{else}} Submit {{/if}} </XReact> </XReact::Root> </form> </template> }The components passed to XReact can be any valid React components, this means you can just do:
<template> <XReact::Root> <XReact @component={{MyIntlProvider}}> <XReact @component={{FormattedMessage}} @props={{id="hello.world"}} /> </XReact> </XReact::Root> </template>Create a backing component class for your HBS template, then add the React component as a property of this class:
import { MyButton } from './my-button.tsx'; export default MyEmberComponent extends Component { myReactButton = MyButton; }Then, you can render your react component by referencing the class property:
See the Contributing guide for details.
This project is licensed under the MIT License.