Phoenix LiveReact

Phoenix LiveReact

4b071f90c5d9c0a58e2d9076460b7be4?s=128

さっちゃん

June 30, 2019
Tweet

Transcript

  1. Phoenix LiveReact

  2. .。oO(さっちゃんですよヾ(〃l _ l)ノ゙ ☆)

  3. Phoenix LiveView https://github.com/phoenixframework/phoenix_live_view

  4. Phoenix LiveView: Interactive, Real-Time Apps. No Need to Write JavaScript.

    https://dockyard.com/blog/2018/12/12/phoenix-liveview- interactive-real-time-apps-no-need-to-write-javascript
  5. _⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈_ > No Need to Write JavaScript. <  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

  6. Write Elixir. defmodule ExampleWeb.CounterLive do use Phoenix.LiveView def render(assigns) do

    ~L""" Count: <%= @count %> """ end def mount(%{}, socket) do if connected?(socket), do: :timer.send_interval(1000, self(), :count_up) {:ok, assign(socket, :count, 0)} end def handle_info(:count_up, socket) do count = socket.assigns.count {:noreply, assign(socket, :count, count + 1)} end end
  7. Write EEx. <%= Phoenix.LiveView.live_render(@conn, ExampleWeb.CounterLive, session: %{}) %> Done!

  8. No Need to Write JavaScript?

  9. Taking the principle of excluded middle from the mathematician would

    be the same, say, as proscribing the telescope to the astronomer or to the boxer the use of his fists. Hilbert (1927)
  10. Taking the JavaScript from the Web UI would be the

    same, say, as proscribing the principle of excluded middle from the mathematician.
  11. UI and the changes of UI are difficult. We can't

    escape from JavaScript.
  12. If there is a useChannel React hook…

  13. Improving UX with Phoenix Channels & React Hooks – Flatiron

    Labs – Medium https://medium.com/flatiron-labs/improving-ux-with- phoenix-channels-react-hooks-8e661d3a771e
  14. defmodule ExampleWeb.RoomChannel do use ExampleWeb, :channel def join("room:lobby", payload, socket)

    do socket = assign(socket, :count, 0) :timer.send_interval(1000, self(), :count_up) {:ok, socket} end def handle_info(:count_up, socket) do count = socket.assigns.count + 1 socket = assign(socket, :count, count) push(socket, "count_up", %{count: count}) {:noreply, socket} end end
  15. import React from "react"; import ReactDOM from "react-dom"; export default

    function main() { ReactDOM.render( <SocketProvider wsUrl={"/socket"} options={{ token: window.userToken }}> <App /> </SocketProvider>, document.getElementById("app") ); }
  16. import { Socket } from "phoenix"; import { createContext, useEffect

    } from "react"; const SocketContext = createContext(); function SocketProvider({ wsUrl, options, children }) { const socket = new Socket(wsUrl, { params: options }); useEffect(() => { socket.connect(); }, [options, wsUrl]); return ( <SocketContext.Provider value={socket}>{children}</SocketContext.Provider> ); } SocketProvider.defaultProps = { options: {} };
  17. import { useContext, useEffect, useReducer } from "react"; function useChannel(channelTopic,

    reducer, initialState) { const socket = useContext(SocketContext); const [state, dispatch] = useReducer(reducer, initialState); useEffect(() => { const channel = socket.channel(channelTopic, {}); channel.onMessage = (event, payload) => { dispatch({ event, payload }); return payload; }; channel.join(); return () => { channel.leave(); }; }, [channelTopic]); return state; }
  18. function appReducer(state, { event, payload }) { switch (event) {

    case "count_up": return { ...state, count: payload.count }; default: return state; } } function App(props) { const initialState = { count: 0 }; const { count } = useChannel("room:lobby", appReducer, initialState); return <div>Count: {count}</div>; } Done!
  19. use-phoenix-channel - npm https://www.npmjs.com/package/use-phoenix-channel