【发布时间】:2020-11-06 23:35:51
【问题描述】:
我正在用 React 创建一个小 RPG。
目前,我有一个带有 useWalk 钩子的玩家,他们将位置传递给该钩子,并且钩子手柄会在他们四处移动时改变它们的位置。
export const Player: React.FC<PlayerProps> = ({ skin, positionIsWalkable}) => {
const [position, setPosition] = useState<Position2D>({x: 8, y: 8});
const { direction, walk } = useWalk(positionIsWalkable, position, setPosition);
这很好用。然后我添加了一个需要知道玩家在哪里的 AI 代理,因此我将玩家的位置状态拉到了 App 级别,这样我就可以创建一个“findClosestPlayer”方法,并将其传递给我的 AI。
现在我想添加多个玩家,但事情变得很棘手...... 这样做真的很方便:
//this would need to be wrapped in useState/useRef to avoid reevaluations every render, but let's ignore that
const playerPositions: Array<[Position2D, Dispatch<SetStateAction<Position2D>>]> = [];
for (let i = 0; i < 1; i++) {
playerPositions.push(
useState<Position2D>({ x: i, y: i })
);
}
return (
{playerPositions.map((positionTuple) => (
<Player
position={positionTuple[0]}
setPosition={positionTuple[1]}
skin={PlayerSprite}
positionIsWalkable={positionIsWalkable}
/>
))}
)
但你不能在循环中使用 useState。
我探索过做类似的事情:
const [playerPositions, setPlayerPositions] = useState<Position2D[]>([]);
const setPlayerPosition = useCallback((playerIndex: number) => (pos: Position2D) => {
setPlayerPositions(prev => {
let copy = prev.slice();
copy[playerIndex] = pos;
return copy;
})
},[]);
但是 setPlayerPosition(playerIndex) 的类型是 (pos: Position2D) => void 而不是 Dispatch
有什么想法吗?我理想的解决方案是为每个玩家提供一个 [Position2D, Dispatch
我的目标是完全在 React 中创建它作为学习目标(这是我第一次在 React 中工作),但也许这种域状态管理真的最好留给 Redux 之类的东西(我还需要这样做)学习)。但如果我能做到的话,我很想在重构和合并 Redux 之类的东西之前完全在 React 中完成这个项目。
【问题讨论】:
标签: reactjs typescript react-hooks use-state