Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ActionCable and React

ActionCable and React

Lightning Talk given at the Tokyo Rails meetup #32 about using ActionCable with React, either with the react_on_rails gem or by having a separate rails API and webpack managed frontend.

robotvert

March 08, 2017
Tweet

More Decks by robotvert

Other Decks in Programming

Transcript

  1. Disclaimer Slides put together a couple of hours ago. Code

    is untested (but bits and pieces taken from actual apps).
  2. Using the react_on_rails gem integrates webpack etc in Rails apps

    can do server side rendering glues together everything for you
  3. How To (1/3) 1. Make your React app following the

    conventions set by React on Rails 2. Expose the components that you need in Rails import Hello from '../components/Hello'; import ReactOnRails from 'react-on-rails'; ReactOnRails.register({ Hello }); 3. Use the exposed components alongside AC channels in your wrapper Rails views <%= content_for :javascript do %> <%= javascript_include_tag "channels/hello" %> <% end -%> <%= react_component("Hello", props: { name: "Julien" }) %>
  4. How To (2/3) 4. Make a channel Server side class

    HelloChannel < ApplicationCable::Channel def subscribed stream_from "hello" end end Client side //= require cable App.hello = App.cable.subscriptions.create("HelloChannel", { received: function(data) { MYAPP.Hello.updateName(JSON.parse(data)); } });
  5. How To (3/3) 5. Prepare your component (quick n' dirty)

    componentDidMount() { MYAPP.Hello = this; } updateName(data) { this.setState({ name: data.name }); } 6. On the server side Mount the ActionCable engine // config/routes.rb mount ActionCable.server => "/cable" Send messages ActionCable.server.broadcast("hello", serialized_name)
  6. With a strict backend and frontend separation webpack for the

    frontend, Rails as a strict API (no views) frontend runs on :8080, API runs on :3000 in dev need to do the usual CORS stu in dev
  7. How To (1/3) 1. Add the ActionCable JS yarn add

    actioncable 2. Here's a channel helper // actionCable.js const ActionCable = require("actioncable"); const connectToChannel = (name, onReceive) => { let cable = ActionCable.createConsumer("ws://localhost:3000/cable"); return cable.subscriptions.create(name, { received: (data) => { onReceive(JSON.parse(data)); } }); }; export { connectToChannel };
  8. How To (2/3) 3. Prepare your component (super quick n'

    dirty) import { connectToChannel } from "../actionCable"; componentDidMount() { connectToChannel("HelloChannel", (data) => { this.setState({ name: data.name }); }); } 4. On the server side // config/routes.rb mount ActionCable.server => "/cable" // config/environments/development.rb config.action_cable.allowed_request_origins = [ "http://localhost:8080" ]
  9. Tips These are WebSockets, you can receive AND send messages.

    You can inspect the WS frames in the Chrome inspector from inside the initial connect request. You don't need to use Redis as a backend, PostgreSQL works just ne: development: adapter: "postgresql" url: "postgres://root:@localhost/myapp_development" ↑ not a dumb DB adapter, it uses PG's LISTEN / NOTIFY