Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

129
Vistas
Conditions in useEffect React

I have a useEffect that subscribes to websocket at startup and adds the data that comes from the server to the operationList list. This list is displayed on the webpage. This is a list of operations performed by construction equipment, which I receive online and could not chage on a backend.

useEffect(() => {
  const ws = new WebSocket('ws://127.0.0.1:8000/ws/')
  ws.addEventListener('message', (e) => {
    const response = JSON.parse(e.data)
      setOperationsList(operationsList => [
      response,
      ...operationsList,
    ]);

  })
  ws.onopen = () => {
    ws.send(JSON.stringify({
    action: "subscribe_to_operations_activity",
    request_id: new Date().getTime(),
  }))
  }
}, [])  

In the same component I have a state, which stores information about the id of the equipment, the report on which is currently displayed on the screen.

const [activeID, setActiveID]  = useState(false)

I need to add to the operationsList not all the data that comes in the server, as it is done now response = JSON.parse(e.data). Instead, I need to check the condition response.id == activeID, and to add to operationsList only those data that satisfy the condition. I can't add activeID to the list of useEffect dependencies because in this case, a new WebSocket subscription will be created every time the activeID changes. I understand that most likely I don't understand some basic things, so I would be grateful for any advice

Added the activeID path:

In my component

const [activeID, setActiveID]  = useState(false)

  const getElementStar = (newID) => {
  setActiveID(newID)
}

Then I pass it to child component as props:

<LeftMenu
  ...
  getElementStar={getElementStar}
  ...
/>

And finally in child component

  const getKey = () => {
    const newID = props.item.id
    props.getElementStar(newID)
  }

  return (
    <ListItemButton sx={{ pl: 4 }} key={props.index} onClick={getKey}>
      <ListItemIcon>
        { props.star === props.index ? <Star/> : <StarBorder/> }
      </ListItemIcon>
      <ListItemText primary={props.item.name} />
    </ListItemButton>
  );
about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

How activeID is supposed to change? Basically, storing something in a state implies that the component need a re-render when this value changes. Which does not seem to be your case here?

So I would suggest to have your activeID stored as a ref


const activeID = useRef('[my id]')

useEffect(() => {
  const ws = new WebSocket('ws://127.0.0.1:8000/ws/')
  ws.addEventListener('message', (e) => {
    const response = JSON.parse(e.data)
      
      setOperationsList(operationsList => [
      ...response.filter(o => o.id === activeID.current),
      ...operationsList,
    ]);

  })
  ws.onopen = () => {
    ws.send(JSON.stringify({
    action: "subscribe_to_operations_activity",
    request_id: new Date().getTime(),
  }))
  }
}, [])  

If activeID needs to change somehow, you can have this by doing

useEffect(() => {
    activeID.current = [my new value]
}, [triggers that could change activeId (maybe a prop?)])

=== EDIT ===

So I assume changing activeID must trigger a re-render to change your <Star > component depending on current activeID right? :)

So I would suggest 2 differents things. Either with the ref, so something like that

const [activeID, setActiveID] = useState();
const activeIDRef = useRef()

on your useEffect having

ws.addEventListener('message', (e) => {
    const response = JSON.parse(e.data)

      setOperationsList(operationsList => [
      ...response.filter(o => o.id === activeIDRef.current),
      ...operationsList,
    ]);
})

and have a second useEffect to change ref when activeID changes

useEffect(() => {
    activeIDRef.current = activeID
}, [activeID])

OR

Maybe it would be easier to keep on storing everything in your operationsList BUT having it filtered when displaying values. If you need it in a state, like this

const [operationsListFiltered, setOperationsListFiltered] = useState([]);
useEffect(() => {
    setOperationsListFiltered(operationsList.filter(o => o.id === activeId))
}, [activeId, operationsList])

Or directly as variable

const operationsListFiltered = useMemo(() => operationsList.filter(o => o.id === activeId), [activeId, operationsList]);

This way, either your activeID OR your operationLists from your websocket changes, your operationsListFiltered will be updated

about 4 years ago · Juan Pablo Isaza Denunciar

0

You can try running a loop with a condition that, once true, will then push what you want to push to the specific list. That will only work if the data you are receiving from the back-end is a type of array.

let dataList = []

    const loopData = () => {
       e.data.forEach((obj) => {
         if (obj.id === activeID) {
            dataList.push(obj)
         } 
       }
    }

useEffect(() => loopData(), []);

And then

setOperationsList(...dataList)
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda