EdgeInteract
useInteractionCallback
useInteractionCallback(interactionId) subscribes to the response for a specific in-flight interaction. It is the React equivalent of watching the callback topic — useful when you sent an interaction from the frontend and want to react to the response in the same component tree.
Signature
function useInteractionCallback<TData = unknown>(
interactionId: string | null
): {
/** The response, once received */
response: InteractionResponse<TData> | null;
/** True if timed out or an error occurred */
error: InteractionError | null;
/** True while waiting for a response */
isPending: boolean;
/** True if the response has been received */
isResolved: boolean;
}
Usage — React-Initiated Approval
This pattern is for cases where a React component initiates an interaction via an API call (not via useInteraction()) and wants to observe the response:
import { useInteractionCallback } from 'edge-interact-react';
function WorkflowApprovalStatus({ workflowId }: { workflowId: string }) {
const [interactionId, setInteractionId] = useState<string | null>(null);
const { response, error, isPending } = useInteractionCallback(interactionId);
useEffect(() => {
// Fetch the interaction ID for this workflow from the server
workflowApi.getHilInteractionId(workflowId).then(setInteractionId);
}, [workflowId]);
useEffect(() => {
if (response) {
// Update UI when the manager responds
console.log('Manager decision:', response.outcome, response.respondedBy);
}
}, [response]);
if (!interactionId) return <p>Loading...</p>;
return (
<div className="approval-status">
{isPending && (
<div className="pending-badge">
Waiting for manager approval...
</div>
)}
{response && (
<div className={`decision-badge ${response.outcome}`}>
{response.outcome === 'approved' ? 'Approved' : 'Rejected'} by {response.respondedBy}
</div>
)}
{error && (
<div className="error-badge">
{error instanceof InteractionTimeoutError
? 'Approval timed out — no response received.'
: `Error: ${error.message}`}
</div>
)}
</div>
);
}
Null interactionId
Pass null as interactionId when there is no active interaction to watch. The hook returns { response: null, error: null, isPending: false, isResolved: false } and does not create any subscriptions.
Cleanup
The hook cleans up automatically when:
- The component unmounts
interactionIdchanges to a new value (old subscription is unsubscribed)interactionIdchanges tonull- The response is received (subscription is unsubscribed after receiving)