Skip to content

Commit

Permalink
fix losing reference to channel if it was lost inbetween setStates (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jdyn authored Jan 6, 2024
1 parent cc8f127 commit 2481302
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 12 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# 0.0.1-alpha.8

2023-1-05

### Breaking changes
None

### Additional changes
* Fix a bug where a component re-render would cause `useEvent` to stop listening and responding to the event correctly if `leave` was recently called.

# 0.0.1-alpha.7

2023-12-27
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "use-phoenix",
"version": "0.0.1-alpha.7",
"version": "0.0.1-alpha.8",
"description": "React hooks for the Phoenix Framework",
"main": "dist/index.js",
"module": "dist/index.esm.js",
Expand Down
23 changes: 14 additions & 9 deletions src/useEvent/useEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,14 @@ export function useEvent<Event extends EventAction>(
): { data: Event['data'] | null } {
const { socket } = usePhoenix();
const handler = useLatest(listener);
const [channel, set] = useState<Channel | null>(null);
const [channel, set] = useState<Channel | undefined>(findChannel(socket, event));

const channelRef = useLatest(channel);

const [data, setData] = useState<Event['data'] | null>(null);

const upsert = useCallback(
(topic: string): Channel | null => {
(topic: string): Channel | undefined => {
if (socket) {
let channel = findChannel(socket, topic);
if (channel) return channel;
Expand All @@ -51,7 +54,7 @@ export function useEvent<Event extends EventAction>(
return channel;
}

return null;
return undefined;
},
[socket]
);
Expand All @@ -74,17 +77,19 @@ export function useEvent<Event extends EventAction>(
}, [identifier, upsert]);

useEffect(() => {
if (channel === null) return;
if (!channelRef.current) return;

const ref = channel.on(event, (message) => {
const ref = channelRef.current.on(event, (message) => {
setData(message);
if (typeof handler.current !== 'function') return;
handler.current(message);

if (typeof handler.current === 'function') {
handler.current(message);
}
});

return () => {
channel.off(event, ref);
set(null);
channelRef.current?.off(event, ref);
set(undefined);
};
}, [channel, event, handler]);

Expand Down
5 changes: 3 additions & 2 deletions src/util.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { PhoenixSocket } from './usePhoenix';
import type { Channel } from 'phoenix';

export const findChannel = (socket: PhoenixSocket, topic: string) =>
socket.channels.find((channel) => channel.topic === topic);
export const findChannel = (socket: PhoenixSocket | null, topic: string): Channel | undefined =>
socket ? socket.channels.find((channel) => channel.topic === topic) : undefined;

0 comments on commit 2481302

Please sign in to comment.