Skip to content

[echo-react] Boost skill examples: presence listeners registered outside useEffect; undefined user in whisper example #521

@systempath

Description

@systempath

Summary

The Boost skill shipped with @laravel/echo-react (resources/boost/skills/echo-react-development/SKILL.blade.php) contains two example bugs that coding agents copy verbatim into applications.

1. Presence-channel listeners registered outside useEffect

In the useEchoPresence example (lines ~112–114 of the published SKILL.blade.php):

function ChatRoom({ roomId }: { roomId: number }) {
    const { channel } = useEchoPresence(`chat.${roomId}`, "NewMessage", (e) => {
        console.log(e.message);
    });

    channel().here((users) => console.log('Current users:', users));
    channel().joining((user) => console.log(`${user.name} joined`));
    channel().leaving((user) => console.log(`${user.name} left`));

    return <div>Chat room {roomId}</div>;
}

channel().here()/.joining()/.leaving() run in the component body, so every re-render registers duplicate listeners on the same channel. They also violate React's render-purity rules (flagged by eslint-plugin-react-hooks v7 and the React Compiler). Suggested fix:

useEffect(() => {
    channel().here((users) => console.log('Current users:', users));
    channel().joining((user) => console.log(`${user.name} joined`));
    channel().leaving((user) => console.log(`${user.name} left`));
}, [channel]);

2. Whisper example references undefined user and whispers during render

In the client-events example (line ~159):

function ChatInput({ roomId }: { roomId: number }) {
    const { channel } = useEcho(`chat.${roomId}`, ['update'], (e) => { ... });

    // Send typing indicator
    channel().whisper('typing', { name: user.name });
    ...
}

user is never declared (compile error as written), and the whisper call executes on every render rather than on a user action. Suggested fix: accept user as a prop and move the whisper into an event handler (e.g. an input's onChange), with listenForWhisper registered inside useEffect.

Context

Found while syncing Boost skills into a Laravel 13 + React 19 app (php artisan boost:update). The framework-agnostic laravel-echo skill is unaffected — these examples exist only in the React skill. We're carrying a project-level .ai/skills/ override in the meantime.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions