reactjs - How to get channel messages in Elixir Phoenix to change the state of a React component? -
i'm trying figure out how state of component update based on external event, , in case external event message coming down elixir phoenix channel.
so basically, have simple h1 tag , must reflect latest thing comes channel. there 2 interlinked questions:
a) how channel component? far have done passing channel prop.
b) how handle messages coming channel inside component? "this.state.chan.on" doesn't work, , seems clumsy.
import socket "./socket" import react "react" import reactdom "react-dom" socket.connect() // connected, can join channels topic: let channel = socket.channel("topic:subtopic", {}) channel.join() .receive("ok", resp => { console.log("joined successfully", resp) }) .receive("error", resp => { console.log("unable join", resp) }) class helloworld extends react.component { state = { chan: this.props.channel, mess: this.props.message } this.state.chan.on("new_message", payload => { this.setstate(prevstate => { return {mess: ${payload.body}} }); }) componentdidmount = () => { console.log("did mount hello world") } render = () => { return (<h1>{this.state.mess}</h1>) } } reactdom.render( <helloworld message={1} channel={channel}/>, document.getelementbyid("hello-world") )
what accepted way of doing this? how messages channel or socket or whatever, generated outside of react , outside of user interface, affect state of components, , related, how outside event piped component in first place? correct put channel component? because seems limit channel's output affecting component, , not other independent ones might want affect.
edit: here compilation error message. yes js may not correct i'm getting syntax error right there on first this.state.chan.on:
17:55:13 - error: compiling of web/static/js/app.js failed. l40:6 unexpected token 38 | } 39 | > 40 | this.state.chan.on( | ^ 41 | 42 | componentdidmount = () => { 43 | console.log("did mount hello world") stack trace suppressed. run `loggy_stacks=1` see trace. 18:07:20 - error: compiling of web/static/js/app.js failed. l40:6 unexpected token 38 | } 39 | > 40 | this.state.chan.on("new_message", payload => { | ^ 41 | this.setstate(prevstate => { 42 | return {mess: ${payload.body}} 43 | }); stack trace suppressed. run `loggy_stacks=1` see trace. 18:07:22 - error: compiling of web/static/js/app.js failed. l40:6 unexpected token 38 | } 39 | > 40 | this.state.chan.on("new_message", payload => { | ^ 41 | this.setstate(prevstate => { 42 | return {mess: ${payload.body}} 43 | }); stack trace suppressed. run `loggy_stacks=1` see trace.
you cannot have this.state.chan.on(...)
in class body outside functions. can put code in constructor though. also, setstate
call contains syntax error , can simplified use object argument. here's how constructor like:
class helloworld extends react.component { constructor(props) { super(); this.state = { chan: props.channel, mess: props.message }; this.state.chan.on("new_message", payload => { this.setstate({mess: payload.body}); }); } ... }
there 1 problem though. on
callback keep getting fired when component unmounted dom. should subscribe messages in componentdidmount
, unsubscribe in componentwillunmount
:
class helloworld extends react.component { constructor(props) { super(); this.state = { chan: props.channel, mess: props.message }; } componentdidmount() { const ref = this.state.chan.on("new_message", payload => { this.setstate({mess: payload.body}); }); this.setstate({ref: ref}); } componentwillunmount() { this.state.chan.off("new_message", this.state.ref); } ... }
wiki
Comments
Post a Comment