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

Phoenix LiveView & React integration #2988

Open
wants to merge 20 commits into
base: main
Choose a base branch
from

Conversation

zeorin
Copy link
Collaborator

@zeorin zeorin commented Mar 5, 2025

Description

This PR adds more idiomatic integration between Phoenix LiveView and React.

Phoenix LiveView and React Components can be interleaved arbitrarily, and they will still participate in their respective lifecycles, however every component that is a child of a React component (even indirectly) will not have diffs sent over the channel on changes. Rendering is still done using patches, but the actual update payload is not diffed. (Note that I think it is possible to solve this but that would be more effort than using targeted portals, as below.)

React components can be mount as a portal in another React component. This way you can have a React Component tree that does not necessarily have to match the DOM tree. This is handy for sharing e.g. context with multiple React components (and also means that you can avoid interleaving Phoenix LiveView and React Components if you are concerned about the over-the-wire perf impact of doing so). Ids are used to associate portals and their targets. These can be nested arbitrarily deeply.

phx-* events Just Work™ because Phoenix LiveView uses event delegation to listen to them.

There's a jsx macro that you can use to create a Phoenix functional component. It will create a functional component with the name of the file, so if you use e.g. jsx("assets/js/react/components/Foo.tsx"), you can then use <.Foo> in an Heex template. You can also annotate the macro call with attr and slot like a regular component. The :inner_block slot is automatically translated to the children prop.

React components included in this way will be included as their own entrypoint by ESBuild, but code that they share dependencies on with the rest of the app will be code-split into separate chunks.

This lays the some of the groundwork for #2850.

Still to be done:

Validation steps

Check out the branch, update deps, and start dev server. Navigate to http://localhost:4000/dev/react to see some demo components

Additional notes for the reviewer

There are still a bunch of TODO comments in the code that need review.

This work has taken inspiration from:

AI Usage

Please disclose how you've used AI in this work (it's cool, we just want to know!):

  • Code generation (copilot but not intellisense)
  • Learning or fact checking
  • Strategy / design
  • Optimisation / refactoring
  • Translation / spellchecking / doc gen
  • Other
  • I have not used AI

You can read more details in our Responsible AI Policy

Pre-submission checklist

  • I have performed a self-review of my code.
  • I have implemented and tested all related authorization policies. (e.g., :owner, :admin, :editor, :viewer)
  • I have updated the changelog.
  • I have ticked a box in "AI usage" in this PR

@zeorin zeorin requested a review from stuartc March 5, 2025 21:24
@zeorin zeorin changed the title 2850 migrate workflow edit to react Phoenix LiveView & React integration Mar 5, 2025
@zeorin zeorin force-pushed the 2850-migrate-workflow-edit-to-react branch 2 times, most recently from add6549 to aeab027 Compare March 5, 2025 21:33
@zeorin zeorin changed the base branch from main to add-eslint March 8, 2025 14:12
@zeorin zeorin force-pushed the 2850-migrate-workflow-edit-to-react branch from 44ba0e5 to cf20f0a Compare March 8, 2025 15:17
Base automatically changed from add-eslint to main March 10, 2025 13:33
@zeorin zeorin force-pushed the 2850-migrate-workflow-edit-to-react branch from cf20f0a to a641536 Compare March 12, 2025 21:50
@zeorin zeorin force-pushed the 2850-migrate-workflow-edit-to-react branch from a641536 to f472c01 Compare March 15, 2025 21:01
@zeorin zeorin marked this pull request as ready for review March 15, 2025 21:01
- Updated `get_entry_points/1` to accept an app atom.
- Adjusted `bootstrap.ex` to call `get_entry_points/1` with the `:lightning` app.
- Cleaned up variable naming and function depth to satisfy credo.
We've got a bit of an issue with using runtime during production builds - since runtime.exs expects pretty much every env variable to be available; which isn't realistic during build time.

This means that the React build tooling (the new macro work on `React`) won't work right now with the automatic entrypoint generator - perhaps we just go the manual route for now.
@doc-han doc-han mentioned this pull request Mar 20, 2025
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: New Issues
Development

Successfully merging this pull request may close these issues.

2 participants