TransWikia.com

Avoid recursive rendering with promises?

Stack Overflow Asked on November 27, 2021

Heres my simplified React component:

import React from "react"
import {useSelector, useDispatch} from "react-redux"
import { useRouteMatch } from "react-router-dom"
import gameService from "../services/game"
import {setGame} from "../reducers/game" //action creator

const Game = () => {
    const game = useSelector(state => state.game)
    const dispatch = useDispatch()

    const match = useRouteMatch('/games/:id')
    gameService.oneGame(match.params.id).then(g => dispatch(setGame(g)))

    const gameInfo = (game) => {
        ...some proceessing
        return(JSX containig info about the game)
    }

    return(
        game ? <div>
            <h2>{game.name}</h2>
            {gameInfo(game)}
         </div> :
         loading
    )
} 

export default Game

Component is called from App.js:

    <Route path="/games/:id">
        <Game />
    </Route>

Everything works but the site renders infinitely. Does the promise resolve after the component has rendered and this renders the component again, or what is happenig here? And what is the easiest fix?

One Answer

I think you may want to put the call to gameService in a useEffect hook so that it is only called when match.params.id and dispatch change rather than every time the component is re-rendered.

Try amending it to be:

import React, { useEffect } from "react"
import {useSelector, useDispatch} from "react-redux"
import { useRouteMatch } from "react-router-dom"
import gameService from "../services/game"
import {setGame} from "../reducers/game" //action creator

const Game = () => {
    const game = useSelector(state => state.game)
    const dispatch = useDispatch()

    const match = useRouteMatch('/games/:id')
    useEffect(() => {
         gameService.oneGame(match.params.id).then(g => dispatch(setGame(g)))
    }, [match.params.id, dispatch]);

    const gameInfo = (game) => {
        ...some proceessing
        return(JSX containig info about the game)
    }

    return(
        game ? <div>
            <h2>{game.name}</h2>
            {gameInfo(game)}
         </div> :
         loading
    )
} 

export default Game

Answered by Spencer Bard on November 27, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP