【问题标题】:useEffect socket.on problem rerendering useStateuseEffect socket.on 问题重新渲染 useState
【发布时间】:2020-12-16 14:13:21
【问题描述】:

我正在寻求使用 socket.io-client 的帮助。我在尝试从聊天服务器获取所有消息时遇到了一些问题。我应该收到一条单独的消息,我需要推送到一个状态。我不会重新呈现每条消息。有没有办法处理状态并更新它?谢谢

import React, {useState, useEffect} from 'react'
import {withRouter} from 'react-router-dom'
import Button from '../core/Button'
import Field from '../core/Field'
import Label from '../core/Label'
import {Container, ScrollContainer} from './StyledComponents'
import useLocalStorageState from '../../hooks/useLocalStorage'
import io from 'socket.io-client'
import {SOCKET_SERVER_CLIENT} from '../../utils/const'
import Profile from '../Profile/Profile'

let socket
const Chat = ({location}) => {
  const [listMessages, setListMessages] = useState([])
  const [message, setMessage] = useState('')

  useEffect(() => {
    const username = location.search.split('=')[1]
    socket = io(`${SOCKET_SERVER_CLIENT}/?username=${username}`)
    return () => {
      socket.disconnect()
    }
  }, [])

  useEffect(() => {
    socket.on('message', message => {
        const auxArr = listMessages
        auxArr.push(message)
        setListMessages(auxArr)
    })
  })

  return (
    <Container>
      {console.log('rerender')}
      <ScrollContainer>
        {listMessages &&
          listMessages.map(infoMessage => (
            <Profile key={infoMessage.time} {...infoMessage} />
          ))}
      </ScrollContainer>
    </Container>
  )
}

export default withRouter(Chat)

【问题讨论】:

    标签: reactjs socket.io


    【解决方案1】:
    const auxArr = listMessages
    auxArr.push(message)
    setListMessages(auxArr)
    

    这段代码正在改变旧数组,然后用同一个数组设置状态。功能组件在设置状态时会进行检查,以确保它已更改。由于前后是同一个数组,因此跳过了渲染。

    您需要复制它,而不是改变状态:

    const auxArr = [...listMessages];
    auxArr.push(message);
    setListMessages(auxArr);
    

    由于你是在旧状态的基础上建立新状态,你还应该使用设置状态的回调形式,以消除如果多个设置状态几乎同时发生时可能发生的任何错误:

    setListMessage(prevMessages => {
      const auxArr = [...prevMessages];
      auxArr.push(message);
      return auxArr;
    })
    

    【讨论】:

    • 您在prevState 示例中出现错误。
    • 就此而言,您可以省略创建新数组并直接在回调中返回一个新数组setListMessages(prevState =&gt; [...prevState, message])
    猜你喜欢
    • 2022-06-18
    • 2020-04-01
    • 2020-12-23
    • 1970-01-01
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-24
    相关资源
    最近更新 更多