How to create a React modal within a Ruby on Rails view?

Hi all,

I’m working on a Ruby on Rails app and I’m getting trouble when I try to create a React component that opens within a RoR view.

Here is my view so far:

<%= link_to react_partner_search_advanced_admin_partners_path(project_id: project.id), data: { remote: true, "partner-search-modal": true } do %> <i class="fab fa-searchengin"></i> <% end %> 

My action in my controller:

def react_partner_search @project = Project.find(params[:project_id]) render layout: false end 

My react_component view:

<%= react_component("PartnerSearchApp", props: { project_address: @project&.project_or_client_full_address }, prerender: false) %> 

And my React component:

import React from 'react'; import Modal from 'react-modal'; import { defaultModalStyles } from '../features/utilities/modalStyles'; const PartnerSearchApp = (props) => { return ( <Modal isOpen={true} style={defaultModalStyles} appElement={document.body}> <h1>{props.project_address}</h1> </Modal> ) } export default PartnerSearchApp; 

When I click on my link, I’m listening for an "ajax:success" event. When it is triggered, I retrieve the response from the server. It is an HTML response that contains the whole 3 points exposed on this page: https://www.shakacode.com/react-on-rails/docs/guides/client-vs-server-rendering/

And this is precisely here that I’m stuck: my component is empty and there is no modal or content within it: <div id="PartnerSearchApp-react-component-xxxxx"> How can I retrieve my whole component and add it to my RoR view?

Thank you so much for your help!

I finally ended with a solution!

In my partner_search_bundle.js, I did:

import ReactOnRails from 'react-on-rails'; import PartnerSearchApp from '../bundles/PartnerSearch/startup/PartnerSearchApp'; // This listener is used to open PartnerSearchModal component. We need // to wait that turbolinks is loaded to look for the modal link element. document.addEventListener("turbolinks:load", () => { const modalLink = document.querySelector('[data-partner-search-modal]'); if (modalLink) { // If server returns a success ajax answer, we retrieve the HTML response that // contains 3 elements we must use to rehydrate our PartnerSearch component: // 1. a script within the head tag, 2. a script within the body tag, 3. a div // within the body tag. More infos here: https://bit.ly/3Dp4atH modalLink.addEventListener("ajax:success", (e) => { const response = e.detail[0]; document.head.append(response.head.children[0]); // We can't iterate through our body response because the append() // function remove the element from the its former parent. document.body.append(response.body.children[0]); document.body.append(response.body.children[0]); // Now we have all the 3 elements on our current body, we can reload the // ReactOnRails script to recreate our component in the current view. ReactOnRails.reactOnRailsPageLoaded(); }); } }) ReactOnRails.register({ PartnerSearchApp }); 

Can be probably improved, but it works so far!

1 Like