Reputation: 146
I am making a game like application where from Game.js file i am passing object to child GameIntro.js file every 3 seconds but it seems i am unable to do it through below code. My intention is that every 3 seconds different objects should pass to child component and remove the previous passed component.
import React from 'react';
import {gdatas} from './gamedata';
import GameIntro from './GameIntro';
const Game = () => {
// const [item, setItem] = useState();
return (
<div>
{gdatas && gdatas.map((gdata,i) => {
return setInterval(() => (
<GameIntro key={i} gdata={gdata} />
),2000)
}
)}
</div>
)
}
export default Game;
import React from 'react';
// import {gdatas} from './gamedata';
const GameIntro = ({gdata}) => {
const gameData = gdata.data.map((elm,i) => {
return (
<div className="col-md-6" key={i}>
<div className="card">
<img src={elm.image} className="card-img-top img-fluid"
alt={elm.word} style={{'width' : '350px' , 'height' : '350px'}} />
<div className="card-body">
<h5 className="card-title mt-3">{elm.word}</h5>
</div>
</div>
</div>
)
})
return (
<div className="row">
{gameData }
</div>
)
}
export default GameIntro;
Upvotes: 0
Views: 219
Reputation: 18939
You don't render the child each item on each loop, just update the props on it. It's actually pretty trivial once you see how:
Example below:
import React, {useState, useEffect, useRef} from "react";
const GameObject = (props) => (
<div className="bar">
{props.current.name}
</div>
)
function App() {
const data = [{name: 'Luke'}, {name: 'Darth'}, {name: 'Yoda'}];
let index = useRef(0);
const [current, setCurrent] = useState(data[index.current]);
useEffect(() => {
function loop() {
setInterval(() => {
index.current = (index.current === data.length - 1) ? 0 : index.current + 1;
setCurrent(data[index.current]);
}, 1000);
}
loop();
}, []);
return (
<div className="App">
<GameObject current={current}/>
</div>
);
}
Upvotes: 1
Reputation: 816910
setInterval
returns an id. It doesn't make sense to return it as part of .map
. You can use setState
and start the interval once (here I'm simulating an interval with setTimeout
):
import React from 'react';
import {gdatas} from './gamedata';
import GameIntro from './GameIntro';
const Game = () => {
const [item, setItem] = React.useState();
React.useEffect(() => {
let id;
function next(i) {
id = setTimeout(function() {
if (i < gdatas.length) {
setState(gdatas[i]);
next(i+1);
}
}, 2000);
}
next(0);
return () => clearTimeout(id);
}, []); // only invoke on first render
return (
<div>
{item && <GameIntro gdata={item} />}
</div>
)
}
export default Game;
Upvotes: 2