ericlathrop

ericlathrop

Phoenix-js-react-hooks - React Hooks for working with Phoenix Channels in JavaScript

I built a silly site for Halloween that uses Phoenix Channels on the backend, and React on the frontend. I had many problems integrating the official phoenix NPM module with my React components. After many iterations I’ve got something that fits in naturally with React function components, so I’ve extracted it as a library to share, and published it on NPM and GitLab.

Here’s part of the README:

phoenix-js-react-hooks

React hooks for working with Phoenix’s channels.

Usage

Wrap the top of your app with a <SocketProvider> so child components will have
access to the socket.

import { SocketProvider } from '@ericlathrop/phoenix-js-react-hooks';

function App() {
  const socketUrl = "wss://localhost:4000/socket";
  const socketOptions = { params: { 'user_id': userId }};

  return (
    <SocketProvider url={socketUrl} options={socketOptions}>
      <Main />
    </SocketProvider>
  );
}

The useChannel hook lets you subscribe to a channel, and the useEventHandler
hook lets you respond to incoming messages:

import React, { useContext, useEffect, useRef, useState } from 'react';
import { sendMessage, useChannel, useEventHandler } from '@ericlathrop/phoenix-js-react-hooks';

export function Main() {
  const [messages, setMessages] = useState([]);

  const room = 'cute kitties';
  const { channel: chatChannel } = useChannel('chat:' + room, undefined, (channel, { messages: initialMessages}) => {
    setMessages(initialMessages);
  });

  useEventHandler(chatChannel, 'new_message', message => {
    setMessages(messages.slice(0).concat([message]));
  });

  return (
    <div className="chat-messages" >
      {messages.map(({ id, message }) => <ChatMessage key={id} message={message} />)}
    </div>
  );
}

Most Liked

ericlathrop

ericlathrop

Correct. I was passing in a lambda so the handler would be different every time the component renders, so the reference needs to get updated.

For example:

  useEventHandler(chatChannel, 'new_message', message => {
    setMessages(messages.slice(0).concat([message]));
    messageWindow.current.scrollTop = messageWindow.current.scrollHeight;
  });

If the reference handler reference never got updated, then the first handler would stay with messages being [] and only the last message would get added for each event.

Where Next?

Popular in Announcing Top

dominicletz
Hi, I thought I had posted my library before but seems I hadn’t. The project is still in early stages but it’s growing and so I think it...
New
asiniy
Hey there! I wrote a download elixir package which does exactly what its name about - an easy way to download files. I saw solutions ...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29305 241
New
OvermindDL1
I created a new library (rather I pulled out a couple files from my big project), it manages an operating system PID file for the BEAM. ...
New
mathieuprog
Hello :wave: Allow me to introduce you to Tz, an alternative time zone database support to Tzdata. Why another library? First and fore...
New
Crowdhailer
The latest release of Ace (0.10.0) includes serving content over HTTP/2. I have started writing a webserver to teach my self more about...
New
seancribbs
Today I released a new dialyzer Mix task as the dialyzex package! At the time we started writing this task, the existing dialyzer integra...
New
jakub-zawislak
Hi everyone, I’m coming from the Symfony (PHP) framework. I like Phoenix, but it has a one thing that was build much better in the Symfo...
New
mplatts
With HEEX released we decided to start a components library using Tailwind CSS - check it out here: Petal Components. We also have a boi...
New
marcuslankenau
I feel kind of stuck with the absence of a proper xml library for Elixir. Currently I use SweetXML which was ok for me more or less to pa...
New

Other popular topics Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

We're in Beta

About us Mission Statement