#ruby-on-rails #webpacker #react-rails
Вопрос:
Каков наилучший способ поделиться пользовательским объектом между несколькими react_component
, кроме как повесить его на окно?
Например —
<%= react_component("HelloWorld1", { user: @user }) %>
<%= react_component("HelloWorld2", { user: @user }) %>
Ответ №1:
Если вы используете React и HTML.ERB для интерфейса
Я думаю, что то, как вы сейчас это делаете, — лучший способ сделать это, если вы хотите объединить HTML.ERB и реагировать.
Точно так же, как вы не можете передать опору сразу двум компонентам при работе с pure React, я не думаю, что вы сможете сделать это и в этом случае.
Если вы используете React только для интерфейса
Примечание: Я не уверен, как следующее повлияет на SEO.
Вы можете использовать приложение Rails в качестве API и отображать приложение React с помощью одного HTML-тега static_pages#root
(или аналогичного). А затем используйте react-router-dom
для маршрутизации и изменения страниц на интерфейсе.
Таким образом, вам не нужно сохранять html.erb
шаблоны визуализации, в которые вы можете передавать переменные экземпляра. Вы бы извлекали данные и изменяли их с помощью запросов API.
Дополнительные сведения
Если вы решите использовать второй метод (с помощью react-router-dom
), то файлы могут выглядеть примерно так:
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;