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 full-size slide

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

    View full-size slide

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

    View full-size 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 full-size slide

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

    View full-size 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 full-size slide

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

    View full-size slide

  8. No Need to Write JavaScript?

    View full-size 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 full-size 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 full-size slide

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

    View full-size slide

  12. If there is a useChannel React hook…

    View full-size 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 full-size 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 full-size slide

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


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

    View full-size 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 full-size 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 full-size 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 full-size slide

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

    View full-size slide