首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在事件上反复呈现的React

在事件上反复呈现的React
EN

Stack Overflow用户
提问于 2022-01-18 03:56:07
回答 1查看 35关注 0票数 1

我在我的网站中使用套接字,其中有一个事件,一个用户可以向服务器发送一个单词,它会向每个人发送(art-addpic)一个与该单词对应的图像URL,但是只有具有isArtist=true的用户才能响应该事件。艺术家的页面应该用接收到的URL更新一次现有的图像URL列表(optionImages)。但是,当事件被接收时,列表中的所有图像都将被接收到的URL替换。此外,呈现图像列表ArtBoard的组件不会用更新的URL重新呈现。我是新来的。我哪里出问题了?

我检查了服务器,事件art-addpic只广播了一次。

Arena.js:(发生这种情况的网页):

代码语言:javascript
运行
复制
import React, { useEffect, useState } from "react";
import Leaderboard from "../comps/Leaderboard";
import { io } from "socket.io-client";
import Service from "../Service";
import DetBoard from "../comps/DetBoard";
import ArtBoard from "../comps/ArtBoard";
const username = "Nick"
const roomkey="abc"
let userid;
if(localStorage.getItem('userid')){
    userid = localStorage.getItem('userid')
}
else{
    userid = Service.makeid(5);
    localStorage.setItem('userid', userid);
}
function useForceUpdate(){
    const [value, setValue] = useState(0); // integer state
    return () => setValue(value => value + 1); // update the state to force render
}
// const [userid,setUserId] = 
const socket = io('http://localhost:3001', {query:"username="+username+"&roomkey="+roomkey+"&userid="+userid});
const Arena = (props)=>{
    const [isArtist, setIsArtist] = useState(false);
    const [focusImage, setFocusImage] = useState('https://i.imgur.com/61HsZCU.jpeg')
    const [players, setPlayers] = useState([]);
    const [optionImages, setOptionImages] = useState([
        'https://i.imgur.com/61HsZCU.jpeg',
        'https://i.imgur.com/61HsZCU.jpeg',
        'https://i.imgur.com/61HsZCU.jpeg',
        'https://i.imgur.com/61HsZCU.jpeg',
        'https://i.imgur.com/61HsZCU.jpeg'
    ])
    useEffect(()=>{
        socket.on('connect',()=>{
            console.log("connected")
        })
        socket.on('players', (data)=>{
            data = JSON.parse(data)
            console.log(data)
            setPlayers(data)
        })
        socket.on('artist', (data)=>{
            if(data===userid){
                console.log('You are an artist, Mr White.')
                setIsArtist(true);
            }
            else{
                setIsArtist(false);
            }
        })    
        socket.on('art-addpic', (data)=>{
            data = JSON.parse(data)
            console.log(data)
            let tempOps =optionImages;
            tempOps.splice(0, 1);
            tempOps.push(data.url)
            console.log(tempOps)
            setOptionImages(tempOps);
        })
    }, [
        optionImages
    ]);
    if(isArtist){
        return(
            <div>
            <Leaderboard players={players}></Leaderboard>
            {/* <ArtBoard></ArtBoard> */}
            <ArtBoard socket={socket} focusImage={focusImage} optionImages={optionImages} setOptionImages={setOptionImages}/>         
        </div>
        );
    }
    else{
        return (
            <div>
            <Leaderboard players={players}></Leaderboard>
            {/* <ArtBoard></ArtBoard> */}
            <DetBoard socket={socket} focusImage={focusImage}/>         
        </div>
        );
    }
}
export default Arena;
EN

Stack Overflow用户

回答已采纳

发布于 2022-01-18 07:01:37

你至少有几个问题

从open.

  • optionImages钩子返回的取消订阅套接字连接的
  1. No清理函数,因此它们仍然保持
  2. 状态,optionImages状态会重新触发useEffect回调,从而创建更多的subscriptions.

钩码

代码语言:javascript
运行
复制
useEffect(() => {
  socket.on('connect', () => {
    console.log("connected");
  });

  socket.on('players', (data) => {
    data = JSON.parse(data);
    console.log(data);
    setPlayers(data);
  });

  socket.on('artist', (data) => {
    if (data === userid) {
      console.log('You are an artist, Mr White.');
      setIsArtist(true);
    } else {
      setIsArtist(false);
    }
  });

  socket.on('art-addpic', (data) => {
    data = JSON.parse(data);
    console.log(data);
    let tempOps = optionImages; // (2) tempOps is reference to optionImages state
    tempOps.splice(0, 1);   // (2) mutation!
    tempOps.push(data.url); // (2) mutation!
    console.log(tempOps);
    setOptionImages(tempOps); // (2,3) saved state reference back into state
  });

  // (1) missing cleanup function
}, [optionImages]); // (3) state updated in hook

据我所知,主要问题是'art-addpic'事件。似乎您希望从optionImages状态中删除第一个元素,并向末尾添加一个新的URL。

如果是这样的话,我有以下建议:

connections.

  • Remove

  • 返回一个清除函数,以取消订阅套接字所有useEffect钩子依赖项,因此当组件挂载以建立套接字订阅时,钩子只运行一次,并在unmounting.

  • Use为optionImages清除作为外部依赖项的状态的功能状态更新时清除它们。

钩码

代码语言:javascript
运行
复制
useEffect(() => {
  socket.on('connect', () => {
    console.log("connected");
  });

  socket.on('players', (data) => {
    const parsedData = JSON.parse(data);
    console.log(parsedData);
    setPlayers(parsedData);
  });

  socket.on('artist', (data) => {
    setIsArtist(data === userid);
  });

  socket.on('art-addpic', (data) => {
    const parsedData = JSON.parse(data);
    console.log(parsedData);

    setOptionImages(optionImages => 
      // Shallow copy into array, append URL, slice & keep last 4 elements
      [...optionImages, parsedData.url].slice(-4),
    );
  });

  return () => {
    socket.removeAllListeners();
  }
}, []);

useEffect(() => {
  if (isArtist) {
    console.log('You are an artist, Mr White.');
  }
}, [isArtist]);
票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70750112

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档