Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Phoenix LiveReact
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
さっちゃん
June 30, 2019
Programming
570
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Phoenix LiveReact
#tokyoex
https://github.com/ne-sachirou/phoenix_react_realtime_example
さっちゃん
June 30, 2019
More Decks by さっちゃん
See All by さっちゃん
火星曆
ne_sachirou
0
28
みんなのオブザーバビリティプラットフォームを作ってるんだがパフォーマンスがやばい #mackerelio #srenext
ne_sachirou
0
1.7k
作ってよかったgraceful shutdownライブラリ #kyotogo
ne_sachirou
0
1.4k
path 依存型って何?
ne_sachirou
0
840
野生の onbording と onbording 設計 #kyototechtalk
ne_sachirou
0
740
メトリックはいかにして見え續ける樣になったか #devio2022
ne_sachirou
0
130
名實一致
ne_sachirou
0
750
まかれるあなとみあ ―Mackerel のしくみを理解する 30 分― @ Hatena Engineer Seminar #16
ne_sachirou
0
3.3k
tacit programming : Point-free, Concatenatives & J
ne_sachirou
0
1.1k
Other Decks in Programming
See All in Programming
Contextとはなにか
chiroruxx
1
370
dRuby over BLE
makicamel
2
390
正しくソフトウェアを作る、前提を疑うための認知の視点 / doubt-premise
minodriven
21
7k
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
260
LaravelLive Japan の裏方のすべて — 第188回 PHP勉強会@東京 (2026-06-24)
suguruooki
2
110
RTSPクライアントを自作してみた話
simotin13
0
630
Vue × Nuxt × Oxc どこまで使える?実運用の現在地
andpad
0
300
Snowflake Summitでの新機能 CoCo / CoWork / snowflake-summit-2026-overall-what-new-coco
tatsuhiro
1
180
エンジニアと一緒にテストコードの設計と実装を改善した話
mototakatsu
0
220
並列実装の現場、2ヶ月間実務でAIを使い倒したAIもPCも私も限界が近い
ming_ayami
0
130
さぁV100、メモリをお食べ・・・
nilpe
0
150
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.3k
Featured
See All Featured
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Code Review Best Practice
trishagee
74
20k
Code Reviewing Like a Champion
maltzj
528
40k
Balancing Empowerment & Direction
lara
6
1.2k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2k
Become a Pro
speakerdeck
PRO
31
6k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.4k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
66
55k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
180
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
170
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
400
Transcript
Phoenix LiveReact
.。oO(さっちゃんですよヾ(〃l _ l)ノ゙ ☆)
Phoenix LiveView https://github.com/phoenixframework/phoenix_live_view
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
_⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈_ > No Need to Write JavaScript. <  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄
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
Write EEx. <%= Phoenix.LiveView.live_render(@conn, ExampleWeb.CounterLive, session: %{}) %> Done!
No Need to Write JavaScript?
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)
Taking the JavaScript from the Web UI would be the
same, say, as proscribing the principle of excluded middle from the mathematician.
UI and the changes of UI are difficult. We can't
escape from JavaScript.
If there is a useChannel React hook…
Improving UX with Phoenix Channels & React Hooks – Flatiron
Labs – Medium https://medium.com/flatiron-labs/improving-ux-with- phoenix-channels-react-hooks-8e661d3a771e
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
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") ); }
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: {} };
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; }
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!
use-phoenix-channel - npm https://www.npmjs.com/package/use-phoenix-channel