Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

127
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda