React Hook - useEffect 相同的代码但有多种行为
React Hook - useEffect same code but severals behaviors
我是 React Hook 的新手,我遵循了几个教程,但恐怕我并不了解所有内容。
我有两个代码几乎相同但行为不同的组件,我不明白为什么。
第一个组件代码:
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;
第二部分:
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;
在我的控制台日志中,我发现了这个:
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
.........
我不明白为什么我的组件“so5Games”一遍又一遍地重新渲染,而 so5Fixture 组件只更新 2 两次(这是我尝试的,因为首先用 0 调用 API,然后用实际参数) ?
你能帮我理解一下吗?
非常感谢!
SO5Games
re-renders 无限期因为状态变量是一个数组,记住 [0, 1] === [0, 1]
会 return false
(因为有两个不同的对象) ,而 0 === 0
将 return true
基本上我会像这样重写你的组件:
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;
我是 React Hook 的新手,我遵循了几个教程,但恐怕我并不了解所有内容。
我有两个代码几乎相同但行为不同的组件,我不明白为什么。
第一个组件代码:
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;
第二部分:
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;
在我的控制台日志中,我发现了这个:
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
.........
我不明白为什么我的组件“so5Games”一遍又一遍地重新渲染,而 so5Fixture 组件只更新 2 两次(这是我尝试的,因为首先用 0 调用 API,然后用实际参数) ?
你能帮我理解一下吗?
非常感谢!
SO5Games
re-renders 无限期因为状态变量是一个数组,记住 [0, 1] === [0, 1]
会 return false
(因为有两个不同的对象) ,而 0 === 0
将 return true
基本上我会像这样重写你的组件:
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;