我是一个反应初学者,我觉得这个问题过去曾被问过几次,但我看不出要使它正常工作是我所缺少的。
我正在写一个基于浏览器的简单游戏。我正在使用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}
}
我在要引用此钩子返回的gameState的组件中使用此钩子。
我期望服务器发送新状态时,我的gameState实际上设置为新状态。当服务器返回新状态时,我确实看到了日志语句,其中打印了一个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>
)
}
}
答案 0 :(得分:0)
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()
。
答案 1 :(得分:0)
安装组件时需要建立套接字连接。因此,您需要useEffect的第二个参数:
useEffect(() => {
// ... connection
}, []) // run on component mount
当某些变量更改时,您也可以使用useEffect
:
useEffect(() => { // additional useEffect hook
// ... changes being detected
}, [gameState])
答案 2 :(得分:0)
仅将套接字返回的数据传递给setGameState挂钩。
client.on("gameStateUpdate", (data: ClientGameState) => {
setGameState(data);
});