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

Phoenix LiveReact

Phoenix LiveReact

さっちゃん

June 30, 2019
Tweet

More Decks by さっちゃん

Other Decks in Programming

Transcript

  1. Phoenix LiveReact

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  5. _⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈_
    > No Need to Write JavaScript. <
     ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

    View Slide

  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

    View Slide

  7. Write EEx.
    <%= Phoenix.LiveView.live_render(@conn, ExampleWeb.CounterLive, session: %{}) %>
    Done!

    View Slide

  8. No Need to Write JavaScript?

    View Slide

  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)

    View Slide

  10. Taking the JavaScript from the Web UI would be the same,
    say, as proscribing the principle of excluded middle from
    the mathematician.

    View Slide

  11. UI and the changes of UI are difficult. We can't escape from
    JavaScript.

    View Slide

  12. If there is a useChannel React hook…

    View Slide

  13. Improving UX with Phoenix Channels &
    React Hooks – Flatiron Labs – Medium
    https://medium.com/flatiron-labs/improving-ux-with-
    phoenix-channels-react-hooks-8e661d3a771e

    View Slide

  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

    View Slide

  15. import React from "react";
    import ReactDOM from "react-dom";
    export default function main() {
    ReactDOM.render(


    ,
    document.getElementById("app")
    );
    }

    View Slide

  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 (
    {children}
    );
    }
    SocketProvider.defaultProps = {
    options: {}
    };

    View Slide

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

    View Slide

  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 Count: {count};
    }
    Done!

    View Slide

  19. use-phoenix-channel - npm
    https://www.npmjs.com/package/use-phoenix-channel

    View Slide