I trying to update human.x
using requestAnimationFrame and useState. I want to add elements called "humans" and use requestAnimationFrame to update the position to humans walk in "world" (using css properties). The method addHumans work but requestAnimationFrame update and empty my list.
World.tsx
import { useState, useEffect } from 'react'
import Human from './Human'
import IHuman from './Human'
type IHuman = {
id: number;
x: number;
y: number;
color: string;
}
export default function World() {
const [humans, setHumans] = useState<IHuman[]>([])
const addHuman = () => {
setHumans([...humans, {id: Math.random(), x: 0, y: 0, color: 'red'}])
}
const animate = () => {
setHumans(humans?.map((human, i) => {
return {...human, x: human.x 1}
}));
// console.log(humans)
requestAnimationFrame(animate);
}
useEffect(() => {
requestAnimationFrame(animate);
}, []); // run once
return (
<>
<button onClick={addHuman}>new human</button>
<main>
{humans?.map(human => {
return <Human key = {human.id} x = {human.x} y = {human.y} color = {human.color} />
})}
</main>
</>
)
}
Human.tsx
export default function Human(props: any) {
return (
<div key={props.id} className="human" style={{ top: props.y 'px', left: props.x 'px', backgroundColor: props.color }}>{props.id}</div>
)
}
CodePudding user response:
This is called a stale state. Update your code like this:
setHumans(humans => humans?.map((human, i) => {
return {...human, x: human.x 1}
}));