I'm new to React Hook and I follow severals tutorials but I'm afraid I'm not understand everything.
I have two components with pretty much the same code but two differents behaviors and I don't understand why.
First component code :
function SO5Fixture(props) {
const [gameweek, setGameWeek] = useState(0)
const previousGWClick = () => {
console.log("previousGW from " gameweek)
setGameWeek(gameweek - 1)
}
const nextGWClick = () => {
console.log("nextGW from " gameweek)
setGameWeek(gameweek 1)
}
useEffect(() => {
console.log("so5fixture useEffect")
getGameWeekInfos()
}, [gameweek])
const getGameWeekInfos = async() => {
console.log("getGameWeekInfos")
var so5Fixture = await APISorare.getSo5Fixture(gameweek)
setGameWeek(so5Fixture['data']['so5fixture_game_week'])
}
return (
<div>
<Container>
...
</Container>
</div>
);
}
export default SO5Fixture;
Second component :
import React, { useEffect, useState } from "react";
import { Container, Row, Col, Button, ButtonGroup, Card, Alert } from "react-bootstrap";
import { LinkContainer } from 'react-router-bootstrap'
import APISorare from "../../utils/APISorare";
function SO5Games(props) {
const [games, setGames] = useState([])
useEffect(() => {
console.log("so5Games useEffect")
getGames()
}, [games])
const getGames = async() => {
console.log("getGames : " props.gameWeek)
var so5Games = await APISorare.getSo5Games(props.gameWeek)
setGames(so5Games['data'])
}
return (
<div>
{
games.map( (game, idx) => (
<Alert key={idx} variant="secondary">
<Row>
<Col md={4}>{game['game_date']}</Col>
<Col md={8}>{game['home_team_name']} {game['home_team_score']}-{game['away_team_score']} {game['away_team_name']}</Col>
</Row>
</Alert>
))
}
</div>
);
}
export default SO5Games;
In my console log, I find this :
so5fixture useEffect
SO5Fixture.js:28 getGameWeekInfos
APISorare.js:24 APISorare : getSo5Fixture
SO5Games.js:12 so5Games useEffect
SO5Games.js:17 getGames : 262
APISorare.js:33 APISorare : getSo5Games
SO5Fixture.js:23 so5fixture useEffect
SO5Fixture.js:28 getGameWeekInfos
APISorare.js:24 APISorare : getSo5Fixture
SO5Games.js:12 so5Games useEffect
SO5Games.js:17 getGames : 262
APISorare.js:33 APISorare : getSo5Games
SO5Games.js:12 so5Games useEffect
SO5Games.js:17 getGames : 262
APISorare.js:33 APISorare : getSo5Games
SO5Games.js:12 so5Games useEffect
SO5Games.js:17 getGames : 262
.........
I don't understand why my component "so5Games" re-render over and over whereas the so5Fixture component update just 2 twice (which is what I attempt because first call API with 0 and then with a real parameter) ?
Could you please help me to understand ?
Thanks a lot !
CodePudding user response:
SO5Games
re-renders indefinitely because the state variable is an array, remember that [0, 1] === [0, 1]
will return false
(because there are two distincts objects), whereas 0 === 0
will return true
Basically I would rewrite your components like this :
function SO5Fixture(props) {
const [gameweek, setGameWeek] = useState(0)
const previousGWClick = () => fetchGameWeekInfos(gameweek - 1)
const nextGWClick = () => fetchGameWeekInfos(gameweek 1)
// fetch game week infos on initial render
useEffect(() => fetchGameWeekInfos(gameweek), [])
const fetchGameWeekInfos = async (week) => {
console.log("fetchGameWeekInfos")
var so5Fixture = await APISorare.getSo5Fixture(week)
setGameWeek(so5Fixture['data']['so5fixture_game_week'])
}
return (
<div>
<Container>
...
</Container>
</div>
);
}
export default SO5Fixture;
function SO5Games(props) {
const [games, setGames] = useState([])
// load the games each time props.gameWeek is updated
useEffect(() => {
console.log("so5Games useEffect")
fetchGames()
}, [props.gameWeek])
const fetchGames = async () => {
console.log("getGames : " props.gameWeek)
var so5Games = await APISorare.getSo5Games(props.gameWeek)
setGames(so5Games['data'])
}
return (...);
}
export default SO5Games;