我是反应的初学者,我觉得这个问题过去已经被问过几次了,但我看不出我错过了什么来解决这个问题。
我正在编写一个简单的基于浏览器的游戏。我正在使用socket-io连接到服务器,并且正在使用自定义钩子来获取服务器发送的状态
export const useSocketState = (serverUrl: string) => {
const [isConnected, setConnected] = useState(false)
const [socketId, setSocketId] = useState('')
const [gameState, setGameState] = useState(DEFAULT_INITIAL_STATE)
useEffect(() => {
const client = socket.connect(serverUrl)
client.on("connect", () => {
console.log("connected with id " + client.id)
setConnected(true)
setSocketId(client.id)
});
client.on("disconnect", () => {
setConnected(false)
});
client.on("gameStateUpdate", (data: ClientGameState) => {
console.dir("Recieved new state from server" + data);
console.dir("GameState is " + gameState);
setGameState(prevState => {
const newState = data
console.log(" new state is " + newState)
return newState
})
});
}, gameState);
return {gameState, isConnected, socketId}
}
我正在一个组件中使用此钩子,在该组件中,我引用了此钩子返回的游戏状态。
我希望当服务器发送新状态时,我的游戏状态实际上设置了新状态。我确实看到了日志语句,当服务器返回新状态时,其中打印了一个 newState,但我没有看到它反映在我正在使用的组件中。
Game component
import React from "react";
import {useSocketState} from "./useSocket";
import {ClientGameState} from "../game/GameState";
export function GameComponent(props: any) {
const {gameState, isConnected, socketId} = useSocketState("http://127.0.0.1:8080");
if (gameState.state === 'created') {
return (
<div>
<p> Game id for this game: {props.location.state.gameId} and playerId: {props.location.state.playerId} </p>
<p>{JSON.stringify(gameState)}</p>
</div>
);
} else {
return (
<div>
<p> Game state is not created </p>
</div>
)
}
}
export const useSocketState = (serverUrl: string) => {
const [isConnected, setConnected] = useState(false)
const [socketId, setSocketId] = useState('')
const [gameState, setGameState] = useState(DEFAULT_INITIAL_STATE);
function socketConnection(){
const client = socket.connect(serverUrl)
client.on("connect", () => {
console.log("connected with id " + client.id)
setConnected(true)
setSocketId(client.id)
});
client.on("disconnect", () => {
setConnected(false)
});
client.on("gameStateUpdate", (data: ClientGameState) => {
console.dir("Recieved new state from server" + data);
console.dir("GameState is " + gameState);
setGameState(prevState => {
const newState = data
console.log(" new state is " + newState)
return newState
})
});
}
useEffect(() => {
socketConnection();
}, []);
return {gameState, isConnected, socketId}
}
连接到套接字后,不再需要使用useEffect()
。
安装组件时需要建立套接字连接。因此,您需要第二个 useEffect 参数:
useEffect(() => {
// ... connection
}, []) // run on component mount
当某些变量发生变化时,您也可以使用useEffect
:
useEffect(() => { // additional useEffect hook
// ... changes being detected
}, [gameState])
如何将从套接字返回的数据传递给 setGameState 挂钩。
client.on("gameStateUpdate", (data: ClientGameState) => {
setGameState(data);
});