Arjun Kumar
Arjun Kumar

Reputation: 146

ReactJS - Passing object every 30 seconds from parent to child component not working

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.

Game.js file::

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;

GameIntro.js file

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

Answers (2)

Samuel Goldenbaum
Samuel Goldenbaum

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

Felix Kling
Felix Kling

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

Related Questions