使用 React Hooks 从 YouTube API 获取数据
Fetching data from YouTube API with React Hooks
我正在尝试用我的 YouTube 频道上的播放列表填充一个页面。我正在使用带钩子的 React 16。
import React, { useEffect, useState } from 'react'
import { Container, Row, Col, Card } from 'react-bootstrap'
import PageHeader from '../components/PageHeader'
import axios from "axios"
const Tutorials = () => {
const [data, setData] = useState({items:[]})
useEffect(() => {
const fetchData = async () => {
const results = await axios(
'https://youtube.googleapis.com/youtube/v3/playlists?part=snippet&channelId=[CHANNEL_ID]&key=[API_EXISTS_AND_TESTED_IN_POSTMAN]'
);
setData(results.data.items)
console.log(results.data.items);
}
fetchData();
}, [data])
return (
<div className="">
<Container>
<PageHeader title="Tutorials" />
<Row xs={1} md={2} className="g-4">
{data && data.map(item => {
return(
<Col xs={12} lg={4}>
<Card className="bg-dark">
<Card.Img variant="top" src={item.snippet.thumbnails.high.url} />
<Card.Body>
<Card.Title>{item.snippet.title}</Card.Title>
<Card.Text>
{item.snippet.description}
</Card.Text>
</Card.Body>
</Card>
</Col>
)
})}
</Row>
</Container>
</div>
)
}
export default Tutorials
这是我得到的。但是,如果我删除 .map() 整个函数并渲染,然后粘贴它并渲染,它将显示。所以连接正在发生。但是我一刷新,我就明白了。是什么赋予了?我想也许数据需要时间来加载,所以我把 setData()
放在 setTimeout 中,并在我尝试渲染数据之前检查数据是否可用,但没有任何效果。邮递员显示我的数据回来了。顺便说一下,YouTube 不提供返回数组。它 returns 一个对象。
我也收到了 403,我不确定它是否相关
尝试用空数组而不是对象来初始化它
const [data, setData] = useState([])
为什么会出现错误
首先使用默认值设置状态:
const [data, setData] = useState({ items:[] })
这会将 data
设置为 { items: [] }
,一个具有名为 items
的 属性 的对象,其值是一个数组。
然后您的组件呈现并运行此行:
data && data.map(item => {
但是{ items: [] }
不是数组,所以它没有map
方法。这就是错误的来源。
然后在渲染之后更新效果的状态:
setData(results.data.items)
这(可能)将 data
设置为一个数组,其格式与您的状态初始默认值不同。
如何修复错误
您要么想使用数组作为默认值:
const [data, setData] = useState([])
那么你的其他代码应该可以正常工作。
或
您想在 read/write 您的状态下使用 items
属性。
setData({ items: results.data.items })
还有类似的东西:
data.items.map(item => {
useEffect 钩子依赖项
最后,这将导致无限重新渲染循环:
useEffect(() => {
const fetchData = async () => {
const results = await axios(
'https://youtube.googleapis.com/youtube/v3/playlists?part=snippet&channelId=[CHANNEL_ID]&key=[API_EXISTS_AND_TESTED_IN_POSTMAN]'
);
setData(results.data.items)
console.log(results.data.items);
}
fetchData();
}, [data])
data
声明为此效果的依赖项,但此挂钩写入 data
。所以这个效果会导致自己重新渲染,无限次。
不过这个效果其实并不依赖于data
,所以可以省略。在这种情况下,应使用空数组 []
作为效果依赖项,效果实际上不使用任何局部变量或状态。
问题是您将状态数据初始化为对象
const [data, setData] = useState({items:[]})
并且当组件进行第一次渲染时,它会尝试映射一个不可能的对象。所以你应该将数据状态初始化为一个数组:
const [data, setData] = useState([])
此外,{data && ...} 也不是必需的,因为 data 是一个数组,它是一个真值。
代码中的第二个问题与 useEffect 有关,因为您将数据作为依赖项并且在 useEffect 中设置数据,这可能会导致再次调用 useEffect。正确的方法是一个空数组作为第二个参数:
useEffect(() => {
const fetchData = async () => {
const results = await axios(
'https://youtube.googleapis.com/youtube/v3/playlists?part=snippet&channelId=[CHANNEL_ID]&key=[API_EXISTS_AND_TESTED_IN_POSTMAN]'
);
setData(results.data.items)
console.log(results.data.items);
}
fetchData();
}, [])
我正在尝试用我的 YouTube 频道上的播放列表填充一个页面。我正在使用带钩子的 React 16。
import React, { useEffect, useState } from 'react'
import { Container, Row, Col, Card } from 'react-bootstrap'
import PageHeader from '../components/PageHeader'
import axios from "axios"
const Tutorials = () => {
const [data, setData] = useState({items:[]})
useEffect(() => {
const fetchData = async () => {
const results = await axios(
'https://youtube.googleapis.com/youtube/v3/playlists?part=snippet&channelId=[CHANNEL_ID]&key=[API_EXISTS_AND_TESTED_IN_POSTMAN]'
);
setData(results.data.items)
console.log(results.data.items);
}
fetchData();
}, [data])
return (
<div className="">
<Container>
<PageHeader title="Tutorials" />
<Row xs={1} md={2} className="g-4">
{data && data.map(item => {
return(
<Col xs={12} lg={4}>
<Card className="bg-dark">
<Card.Img variant="top" src={item.snippet.thumbnails.high.url} />
<Card.Body>
<Card.Title>{item.snippet.title}</Card.Title>
<Card.Text>
{item.snippet.description}
</Card.Text>
</Card.Body>
</Card>
</Col>
)
})}
</Row>
</Container>
</div>
)
}
export default Tutorials
这是我得到的。但是,如果我删除 .map() 整个函数并渲染,然后粘贴它并渲染,它将显示。所以连接正在发生。但是我一刷新,我就明白了。是什么赋予了?我想也许数据需要时间来加载,所以我把 setData()
放在 setTimeout 中,并在我尝试渲染数据之前检查数据是否可用,但没有任何效果。邮递员显示我的数据回来了。顺便说一下,YouTube 不提供返回数组。它 returns 一个对象。
我也收到了 403,我不确定它是否相关
尝试用空数组而不是对象来初始化它
const [data, setData] = useState([])
为什么会出现错误
首先使用默认值设置状态:
const [data, setData] = useState({ items:[] })
这会将 data
设置为 { items: [] }
,一个具有名为 items
的 属性 的对象,其值是一个数组。
然后您的组件呈现并运行此行:
data && data.map(item => {
但是{ items: [] }
不是数组,所以它没有map
方法。这就是错误的来源。
然后在渲染之后更新效果的状态:
setData(results.data.items)
这(可能)将 data
设置为一个数组,其格式与您的状态初始默认值不同。
如何修复错误
您要么想使用数组作为默认值:
const [data, setData] = useState([])
那么你的其他代码应该可以正常工作。
或
您想在 read/write 您的状态下使用 items
属性。
setData({ items: results.data.items })
还有类似的东西:
data.items.map(item => {
useEffect 钩子依赖项
最后,这将导致无限重新渲染循环:
useEffect(() => {
const fetchData = async () => {
const results = await axios(
'https://youtube.googleapis.com/youtube/v3/playlists?part=snippet&channelId=[CHANNEL_ID]&key=[API_EXISTS_AND_TESTED_IN_POSTMAN]'
);
setData(results.data.items)
console.log(results.data.items);
}
fetchData();
}, [data])
data
声明为此效果的依赖项,但此挂钩写入 data
。所以这个效果会导致自己重新渲染,无限次。
不过这个效果其实并不依赖于data
,所以可以省略。在这种情况下,应使用空数组 []
作为效果依赖项,效果实际上不使用任何局部变量或状态。
问题是您将状态数据初始化为对象
const [data, setData] = useState({items:[]})
并且当组件进行第一次渲染时,它会尝试映射一个不可能的对象。所以你应该将数据状态初始化为一个数组:
const [data, setData] = useState([])
此外,{data && ...} 也不是必需的,因为 data 是一个数组,它是一个真值。
代码中的第二个问题与 useEffect 有关,因为您将数据作为依赖项并且在 useEffect 中设置数据,这可能会导致再次调用 useEffect。正确的方法是一个空数组作为第二个参数:
useEffect(() => {
const fetchData = async () => {
const results = await axios(
'https://youtube.googleapis.com/youtube/v3/playlists?part=snippet&channelId=[CHANNEL_ID]&key=[API_EXISTS_AND_TESTED_IN_POSTMAN]'
);
setData(results.data.items)
console.log(results.data.items);
}
fetchData();
}, [])