I'm trying to write some inter-frame-comunication hook and I'm not sure that the implementation is correct. Unfortunately, the react lifecycle topic seems very complex (example) and I couldn't find a definite answer or recommendation about how to implement it correctly.
Here's my attempt at writing the hook:
const frame = /*...*/;
let messageId = 0;
function usePostMessage(
eventName: string,
handler: (success: boolean) => void
) {
const [pendingMessageId, setPendingMessageId] = useState<number>();
const postMessage = useCallback(() => {
frame.postMessage(eventName);
setPendingMessageId(++messageId);
}, [eventName]);
useEvent(
"message",
useCallback(
(message) => {
if (
message.eventName === eventName &&
message.messageId === pendingMessageId
) {
handler(message.success);
setPendingMessageId(undefined);
}
},
[eventName, handler, pendingMessageId]
)
);
return { postMessage, pendingMessageId };
}
(I'm using useEvent
)
Usage:
const { postMessage, pendingMessageId } = usePostMessage(
"eventName",
(success) => {
console.log("eventName", success ? "succeeded" : "failed");
}
);
if (pendingMessageId !== undefined) {
return <div>Pending...</div>;
}
return <button onclick={postMessage}>Click me</button>;
As you can see, I tried to implement a way to post a message and get a response from a frame. I also tried to avoid pitfalls such as getting unrelated responses by keeping a message counter.
It works, but I'm afraid that the "message" event might arrive before the setPendingMessageId
state is updated. Is that possible? Are there any guidelines or best practices for implementing this correctly? Thanks.