我有一个组件Player
,它返回一个带有图像的div,它有属性x
和y
,这些属性在Player
内部作为div的左值和顶值传递,在Player
组件外部,我有状态playerCoordinate
,它作为Player
的x
和y
属性值传递。
只要按下左箭头键,playerCoordinate
就会更新,我看到按下左箭头键时playerCoordinate
更新得很好,但是尽管playerCoordinate
更新了,但它并没有更新x
和y
的值。
下面是代码:
屏幕.js
import { useState, useEffect } from 'react'
import styles from './ScreenStyles'
import ScriptDisplayer from '../ScriptDisplayer/ScriptDisplayer';
import Player from '../Player/Player'
function Screen() {
const [playerCoordinate, setPlayerCoordinate] = useState({x: 641, y: 258})
function handleUserKeyPress(event) {
if (event.code === 'ArrowLeft') {
console.log(event, playerCoordinate)
setPlayerCoordinate((prev) => {
prev.x -= 1;
return prev;
})
}
}
useEffect(() => {
window.addEventListener('keydown', handleUserKeyPress)
}, [playerCoordinate])
return (
<>
<div id='screen' style={styles.screen}>
<ScriptDisplayer />
<Player x={playerCoordinate.x} y={playerCoordinate.y} />
</div>
</>
);
}
export default Screen
播放器.js
import playerGif from '../../assets/player.gif'
const styles = {
playerGif: {
height: 70,
width: 70,
}
}
function Player(props) {
console.log('playerX: ', props.x, 'playerY: ', props.y)
return(
<div id='player' style={{position: 'absolute', left: `${props.x}px`, top: `${props.y}px`}}>
<img id='playerGif' src={playerGif} style={styles.playerGif} />
</div>
);
}
export default Player
我对React并不是很陌生,找不到任何合适的解决方案。这里可能出了什么问题?
3条答案
按热度按时间wb1gzix01#
使用spread运算符触发useState更改
b5buobof2#
1.您需要返回一个新对象以识别状态更改。请使用spread syntax从以前的对象创建一个新对象,然后更新所需的属性。
1.不需要在每次状态更改时添加侦听器。使用空依赖项数组表示只希望在装入组件时添加一次侦听器。
1.然后,您应该添加一个cleanup函数,以便在卸载组件时删除侦听器。
tzdcorbm3#
嘿我只是对你的代码做了些修改让它能在我的本地运行。
所有更改都在screen.js文件中,问题是如何使用setPlayerCoordinate更新状态。
此部分更加优化,处理取消订阅和使用React Way