Общий доступ к пользовательскому объекту между несколькими компонентами react_

#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;