Search code examples
node.jsreactjsdatabasesocket.iouse-effect

Is this good design for updating/deleting from list using useState and useEffect?


I'm trying to create a React app that:

  • sends data (json message) from backend to frontend using socket.io
  • if a json message with same is sent, update the existing list

This is how i'm implementing it right now but i'm not sure if this is a good design methodology or if there's a better way to achieve what I want to do.

function App(){
    
    const [database, setDatabase] = useState([])
    
    useEffect(() => {
        socket.on('incoming_data', (data) => {
            
            setDatabase((currentList) => {
                if (currentList.length > 0){ //only check for update/delete if more than 1 item present
                    let exists = !!currentList.find((item) => item.ID === data.ID)
                    
                    if (exists){ //if new item exists in database list
                        if (data.deleteFlag === true){ // incoming data will have a json field declaring whether to delete or not
                        
                            //deleting item
                            var item = currentList.find(itm => itm.ID === data.ID)
                            let ind = currentList.indexOf(item)
                            return (currentList.splice(ind,1))
                        }
                        else{ // else if delete flag is not true... update fields
                            var item = currentList.find(itm => itm.ID === data.ID)
                            let ind = currentList.indexOf(item)
                            
                            if (item.dataField !== data.dataField){
                                currentList[ind].dataField = data.dataField
                            }
                            return (currentList)
                        }
                    }
                    //if incoming data doesnt exist in list, add to it
                    else{ return([...currentList, data]) }
                }
            }
            // if there are 0 items in list, add to list
            else { return ([...currentList, data]) }
        })
    }, [socket])

    return(/*using map to display list in front end*/)
}

Right now, this code works in the following ways:

  • Checks if there are 0 items in 'database', if so, it adds items to it.

What it's not doing:

  • updating items in database
  • deleting items properly. Sometimes it deletes items, other times it does nothing.

Any help would be great!


Solution

  • Use higher-order functions to simplify code like filter, findIndex, etc.

    use findIndex method to check items exist and use the same index to update currentList.

    use the filter function to delete items from the list.

    function App() {
    
      const [database, setDatabase] = useState([])
    
      useEffect(() => {
        socket.on('incoming_data', (data) => {
    
          setDatabase((currentList) => {
            if (currentList.length > 0) { //only check for update/delete if more than 1 item present
              // Use same index to find item
              let itemIndex = currentList.findIndex((item) => item.ID === data.ID)
              if (itemIndex !== -1) { //if new item exists in database list
                if (data.deleteFlag === true) { // incoming data will have a json field declaring whether to delete or not
                  // use filter for delete
                  return currentList.filter((item) => item.ID !== data.ID);
                }
                else {
                  let item = currentList[itemIndex]
                  const newItem = { ...item, dataField: data.dataField }
                  if (item.dataField !== newItem.dataField) {
                    currentList[itemIndex] = newItem;
                    return [...currentList]; // Set new value for updates
                  }
                  return (currentList)
                }
              }
              //if incoming data doesn't exist in list, add to it
              else { return ([...currentList, data]) }
            }
            // if there are 0 items in list, add to list
            else { return ([...currentList, data]) }
          });
        });
      }, [socket])
      return (/*using map to display list in front end*/)
    }