我在我的網站中使用套接字,并且有一個用戶可以向服務器發送一個單詞的事件,服務器會art-addpic向每個人發出 () 對應于該單詞的影像 URL,但只有用戶isArtist=true才能回應該事件。藝術家的頁面應該使用接收到的 URL 更新現有的影像 URL 串列 ( optionImages) 一次。但是當接收到事件時,串列中的所有影像都會被接收到的 URL 替換。此外,渲染影像串列的組件ArtBoard不會使用更新的 URL 重新渲染。我是反應新手。我哪里錯了?
我檢查了服務器,該事件art-addpic僅廣播一次。
Arena.js:(發生這種情況的網頁):
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;
uj5u.com熱心網友回復:
你至少有幾個問題:
- 沒有從鉤子回傳的清理函式
useEffect來取消訂閱套接字連接,因此它們保持打開狀態。 optionImages狀態突變。- 更新
optionImages狀態會重新觸發useEffect創建更多訂閱的回呼。
掛鉤代碼
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。
如果是這種情況,那么我有以下建議:
- 回傳清理函式以取消訂閱套接字連接。
- 洗掉所有
useEffect掛鉤依賴項,以便在組件安裝時掛鉤運行一次以建立套接字訂閱,并在卸載時清理它們。 - 使用功能狀態更新
optionImages將狀態作為外部依賴項洗掉。
掛鉤代碼
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]);
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/416586.html
標籤:
下一篇:無法安裝某些python模塊
