Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support React with multiple mount points #3204

Conversation

mercedesb
Copy link
Contributor

I rule and have completed some work on Case Manager that's ready for review!

This PR introduces React in a way that will allow us to incrementally migrate existing JS to React.

  • Uses our existing JS bundler, esbuild, via our existing bundling system jsbundling-rails
    • Pros: Keeps things simple, doesn't introduce any new tools, isn't Webpacker, and leaves the door open if we want to switch from esbuild to something else in the future
  • Adds React and creates a mount function to allow us to have multiple mount points
    • Pros: we don't have to go all-in on a SPA architecture and can stick with Rails for 90% of our use cases
  • Creates a reusable ViewComponent, called ReactComponent, to make rendering React components in our erb files easy
    • Pros: Keeps Ruby code in Ruby and more easily testable. If we have to do fancy data munging before passing props, we can inherit from this base class and add that logic to the private props method
  • Adds the i18n-js Ruby gem to auto-generate JSON translation files from our existing YML translation files. And adds the companion i18n-js JS package to read and apply the translations.
    • Pros: All of our rails i18n yml files are the source of truth for our translations. We don't need to maintain multiple files since the JSON translations will be autogenerated. And we can use these translations in non-React too if we have a need for that.
  • Adds a little reusable hook for us to make it easy to get translations in React components.

Example for how to use React with this setup

Step 1: Write a React component

This snippet assumes fancy-component.jsx lives in app/javascript/src/components. It must be a .jsx file but you can nest folders however you want.

import mount from "../mount";
import { usei18n } from "../hooks";

const FancyComponent = ({ ...props }) => {
  const i18n = usei18n();

  const handleClick = () => {
      // fancy logic
  }

  return (
    <button className="btn" onClick={handleClick}>
      {i18n.t('fancy.button_text')}
    </button>
  )
};

mount({
  FancyComponent
});

Step 2: Import your component to app/javascript/application.js so it'll be included in the bundle

import './src/components/fancy-component';

Step 3: Render your component in ERB

<%= render ReactComponent.new("FancyComponent", raw_props: { fancy: 'props' }) %>

For reviewer:

  • Adjust the title to explain what it does for the notification email to the listserv.
  • Tag this PR:
    • feature if it contains a feature, fix, or similar. This is anything that contains a user-facing fix in some way, such as frontend changes, alterations to backend behavior, or bug fixes.
    • dependencies if it contains library upgrades or similar. This is anything that upgrades any dependency, such as a Gemfile update or npm package upgrade.
  • If it contains neither, no need to tag this PR.

Copy link
Member

@colinxfleming colinxfleming left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a new era! @mercedesb please continue your work on figuring out how something like autosave or autorefresh / some backend data fetch works against this; once we have a workable example of that we can start breaking this up a bit and migrate over piece by piece. As for this PR this is pretty much a noop as written, so in it's going. outstanding work here getting this to play nice with i18n.

@colinxfleming colinxfleming merged commit 06e3b70 into DARIAEngineering:main May 26, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants