reactjsreact-hookssails.jssails.io.js

update data in state array on socket event


Here is my code:

import React, { useEffect, useState } from 'react';

import Loader from './Loader.jsx';
import Unit from './Unit.jsx';
import Comments from './Comments.jsx';

export default function App() {

  const [unit, setUnit] = useState(null);
  const [comments, setComments] = useState([]);


  useEffect(() => {
    // subscribing to unit's updates
    io.socket.get(`/unit/${window.unitid}/subscribe`, (resData) => {
      setUnit(resData.unit);
      setComments(resData.comments);
    });

    // 'unit' event is fired when a comment is added to the unit
    io.socket.on('unit', (event) => {
      if (event.verb === 'addedTo') {
        console.log('NEW COMMENT ADDED');
        const c = comments; // <-- comments is empty
        c.push(event.added);
        setComments(c);
      }
    });
  }, []);  

  if (!unit) {
    return <Loader />;
  }

  return (
    <>
      <Unit unit={unit} />
      <Comments comments={comments} />
    </>
  )
}

I want to push the newly added comment to comments but the array is empty. However, <Comments /> is properly populated with comments. How can I update comments on socket event ?


Solution

  • Answer was given on Reddit. Using functional update.

    io.socket.on('unit', (event) => {
      if (event.verb === 'addedTo') {
        console.log('NEW COMMENT ADDED');
        setComments( prev => [...prev, event.added])
      }
    });