DEV Community

Rajasegar Chandran
Rajasegar Chandran

Posted on

React inside Ember - The Second Chapter

A year ago, I wrote an article here about invoking React components from Ember where I outlined an approach of rendering React components inside Ember templates or components using a complex and sophisticated mechanism.

After trying it out in our organization, we have found that there are a lot of downsides and productivity concerns in implementing that approach.

Limitations of the old approach

  • Converting existing repo to a workspace or monorepo
  • Setup complex build tooling with webpack
  • Extra wrapper components for passing in props
  • No hot module reloading support
  • Cannot yield child components from Ember

Advantages of the new approach

With the new addon approach by using the ember-react-fc addon, the process looks much simpler and we can overcome many downsides that were outlined in the previous post. Let's discuss the advantages of the new approach one by one here in detail.

Image description

No workspace or monorepo setup required

With this new approach, you don't have to convert your repo to a monorepo or workspace like we did in the old one. You can simply put your React components inside the app/components, may be with a new namespace like app/components/react and use it like this:

<React::HelloWorld @name="Raja"/>
Enter fullscreen mode Exit fullscreen mode

No complex setup required

Previously, we have been compiling React component code using babel plugins using webpack config in Ember cli using the auto-import plugin. The problem with this approach is that, we need to install a lot of dependencies like babel plugins, react libraries and have to configure the webpack in such a way that it picks up only the files with JSX extensions referred from a different package inside a workspace.

Image description

ember-react-fc

ember-react-fc is an Ember addon to incrementally migrate your Ember code starting from components to React. This addon supports the latest React version 18 and functional components. The addon takes care of a lot of things like adding the respective babel plugins to compile JSX, react and react-dom dependencies to your Ember projects, support for .jsx extensions inside your Ember apps and so on.

You can install it in your Ember projects like below and start writing your components in React and they will work out of the box.

ember install ember-react-fc
Enter fullscreen mode Exit fullscreen mode

This addon also comes with a component blueprint so that you can also generate component boiler plates for your React component.

You can generate React components like this:

ember generate react-component hello-world
Enter fullscreen mode Exit fullscreen mode

No wrapper components required

In the old approach, we need to create Ember wrapper components for each React component we were creating. This creates an unnecessary overhead to have Ember duplicates for React components. But with this approach we are just invoking React components inside Ember templates and components in Ember way.

<div>
<h3>I am a Ember Component</h3>
<HelloReact @message={{this.message}}
            @onClick={{this.toggle}} />
</div>
Enter fullscreen mode Exit fullscreen mode

Automatic reloading

In the old approach, we have kept our React components inside a (yarn or pnpm) workspace, so the changes inside this workspace won't affect the Ember build. Since Ember will only look for changes inside the app/ folder, it was proving very difficult to propagate the changes in React components to Ember build pipeline.

This problem we overcame in the new approach since we are keeping the React components inside the Ember app itself, any change you make to your React components will automatically get picked up by ember-cli.

Image description

React can have Ember children

There was no way previously to pass Ember components as children to React components in the old approach. But now you can put Ember components inside React as children. There is some room for misunderstanding here. What I meant by using Ember components as children is that when you are using the markup in your Ember templates, you can give Ember components as children to React components but not inside JSX in React.

This will work:

<React::HelloWorld @name="Raja"> 
<MyEmberComponent @arg1="abc" @arg2=true />
</React::HelloWorld>
Enter fullscreen mode Exit fullscreen mode

This won't work:

import React from 'react';
import WithEmberSupport from 'ember-react-fc';

export default WithEmberSupport(function FunctionalComponent({message, onClick}) {

  return (
    <div id="wrapper" aria-label="hello">
      <button onClick={onClick}>Toggle</button>
      <div>you said: {message}</div>
      <MyEmberComponent @arg1="abc" @arg2=true />
    </div>
  );
});
Enter fullscreen mode Exit fullscreen mode

This is a sample Ember app with the addon ember-react-fc installed and React components created and rendered inside Ember templates.

Image description

Inspiration

The inspiration for this addon came from previous works by Alex LaFroscia like ember-react-components. But that project got abandoned some 3 years ago and it is not made for the latest React versions. I cleaned up the addon by removing the logic for class components, made it work with latest React v18, fixed some issues and so on.

Hope you enjoyed the post and let me know your feedback and thoughts in the comment section. Please give the addon a try and let me know for any issues.

Top comments (0)