Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Deno fresh – List in island not updating

I’m creating a websocket based chat app to experiment with Fresh, but I’m struggling to render a basic list of messages to the page. Here’s some code:

routes/chat.tsx

export default function Chat() {
    return (
        <div>
            // ...
            <MyIsland username={username.value}></MyIsland>
        </div>
    )
}

islands/MyIsland.tsx

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

export default function MyIsland(props: IslandProps) {

    const ws = useSignal<WebSocket | null>(null);
    const messageList = useSignal<Message[]>([]);

    useEffect(() => {
        if (props.username) {
            ws.value = new WebSocket("ws://localhost:5000?username=" + props.username);
            ws.value.onopen    = ()  => { console.log('Connected..') }
            ws.value.onmessage = updateMessages;
        }
    }, []);

    const updateMessages = useCallback((m: MessageEvent<string>) => {
        const data: WsData = JSON.parse(m.data);
    
        if (data.type == SocketMessageType.Text){
            const message: Message = data.value;
            messageList.value.push(message);
        }
    }, [])

    const send = useCallback((text: string) => {
        if (ws.value) {
            const data = // ...
            ws.value.send(JSON.stringify(data));
        }
    }, [ws]);

    return (
        <div>
            <Button onClick={() => send('test')}>Send</Button>
            <div>
                {messageList.value.map((m) => ( <MessageItem {...m} /> ))} // problem here
            </div>
        </div>
    )
}

I would expect the messageList.value.map at the bottom of MyIsland to be updated on the page as the list fills with messages, but this is not the case. I have verified that the list is being updated correctly in the background, it’s just the html that is not updated. I’m very new to fresh and server+client rendered frameworks in general so I suspect I might be misunderstanding the way the islands are rendered. Thanks for any help!

>Solution :

Your state isn’t getting updated because your array reference doesn’t change. You need to assign a new array to messageList.value in order to make it update the state.

Instead of

messageList.value.push(message);

do

messageList.value = […messageList.value, message];

And it will work as you expect it.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading