What is the best way to share a user object between multiple react_component
other than hanging it off of window?
For example -
<%= react_component("HelloWorld1", { user: @user }) %>
<%= react_component("HelloWorld2", { user: @user }) %>
What is the best way to share a user object between multiple react_component
other than hanging it off of window?
For example -
<%= react_component("HelloWorld1", { user: @user }) %>
<%= react_component("HelloWorld2", { user: @user }) %>
I think the way you currently have it is the best way to do it if you want to combine HTML.ERB and React.
Just as you can't pass down a prop to two components at once when dealing with pure React, I don't think you can do it in this case too.
Note: I'm not sure how the following would affect SEO.
You could use the Rails app as an API, and display your React app using a single HTML tag in static_pages#root
(or similar). And then use react-router-dom
for routing and changing pages on the frontend.
That way you don't have to keep rendering html.erb
templates that you may pass instance variables to. You'd be fetching data and modifying it using API requests.
If you choose to do the second method (using react-router-dom
), then the files might look something similar to the following:
routes.rb
Rails.application.routes.draw do
namespace :api, default: { format: :json } do
resources :users, only: [:index, :show, :create, :destroy]
# ...
end
root to: 'static_pages#root'
end
app/controllers/static_pages_controller.rb
class StaticPagesController < ApplicationController
def root
end
end
app/views/static_pages/root.html.erb
<main>
<%= react_component("App") %>
</main>
app/javascript/components/App.jsx
import React, { useState, useEffect } from 'react';
import {Switch, Route} from 'react-router-dom';
import { Auth } from './auth/Auth.jsx';
import { HelloWorld1 } from './hello/world1/HelloWorld1.jsx';
import { HelloWorld2 } from './hello/world1/HelloWorld2.jsx';
const App = () => {
const [user, setUser] = useState(null);
if (!user) {
return (
<Auth setUser={setUser} />
);
}
return (
<Switch>
<Route
exact
path="/hello/world1"
render={(props) => <HelloWorld1 user={user} {...props} />}
/>
<Route
exact
path="/hello/world2"
render={(props) => <HelloWorld2 user={user} {...props} />}
/>
{/* ... */}
</Switch>
};
export default App;