使用 next.js 使用动态 url 获取数据时,find(...) 未定义
find(...) is undefined when fetching data with dynamic url using next.js
当我在主页中获取数据时,一切都如我所愿
但是当我使用相同的代码但使用动态 url 在另一个文件夹中获取数据时,我在尝试对数组使用方法时遇到错误。当我 console.log 获取数据时,我得到了与主页相同的数组
当我删除 Link 并且只想查看 book.title
时,它起作用了。但是当我想从资源中获取数据时出现错误。
mainpage.js
const [data, setData] = useState(null);
const [isLoading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
fetch('https://gnikdroy.pythonanywhere.com/api/book')
.then((res) => res.json())
.then((data) => {
setData(data);
setLoading(false);
});
}, []);
return(
<div>
{data.results.map((book, index) => (
<div key={index}>
<h1>{book.title}</h1>
<Link href={`/reader/${book.id}`} passHref>
<h2>
{
book.resources.find(
({ type }) => type === 'application/epub+zip'
).uri
}
</h2>
</Link>
</div>
))}
</div>
)
searchPage.js
const router = useRouter();
const { name } = router.query;
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
fetch(`https://gnikdroy.pythonanywhere.com/api/book/?search=${name}`)
.then((res) => res.json())
.then((data) => {
setData(data);
setLoading(false);
console.log(data);
});
}, []);
return(
<div>
{data.results.map((book, index) => (
<div key={index}>
<h1>{book.title}</h1>
<Link href={`/reader/${book.id}`} passHref>
<h2>
{
book.resources.find(
({ type }) => type === 'application/epub+zip'
).uri
}
</h2>
</Link>
</div>
))}
</div>
)
我的 console.log 在 searchPage.js
中获取
您的响应数据有时没有获取资源字段。
这就是 book.resources
可以未定义(或)为空的原因。
您可以轻松使用Optional Changing(?.)
替换:
{
book.resources?.find(
({ type }) => type === 'application/epub+zip'
)?.uri || ''
}
除了 Wu Woo 的回答,当考虑 React 如何渲染你的代码时,
首先将执行 return
,然后仅在页面加载时执行 useEffect
,因为 useEffect
依赖数组中没有值。
所以在您的场景中,您在初始页面加载时有 data = null。所以当渲染下面的代码时,因为 data = null data.results
不能使用 Arrays.map().
然后将执行 useEffect
并在其中设置 API 调用中的值 return 并将该值设置为数据。
为避免渲染未定义错误,您必须确保 data.results
不等于 null/undefined,并且当存在 data.results
时渲染您想要的内容。
您可以通过以下方式实现。
可选的链接运算符 (?.) 作为 Wu Woo 的回答,当引用或函数可能是 undefined or null
时,它简化了通过连接对象访问值的过程。那么当 book.resources
等于 null/undefined.
时就不会报上面的错误了
仅当 data.results
和 book.resources
有值时才渲染,否则不会像下面那样。
// Here conditionally check whether there is value for data?.results and if so render this.
{data?.results && data.results.map((book, index) => (
<div key={index}>
<h1>{book.title}</h1>
<Link href={`/reader/${book.id}`} passHref>
<h2>
{/* Here also conditionally check whether there is value for book?.resources and if so render this. */}
{ book?.resources &&
book.resources.find(
({ type }) => type === 'application/epub+zip'
).uri
}
</h2>
</Link>
</div>
))}
当我在主页中获取数据时,一切都如我所愿 但是当我使用相同的代码但使用动态 url 在另一个文件夹中获取数据时,我在尝试对数组使用方法时遇到错误。当我 console.log 获取数据时,我得到了与主页相同的数组
当我删除 Link 并且只想查看 book.title
时,它起作用了。但是当我想从资源中获取数据时出现错误。
mainpage.js
const [data, setData] = useState(null);
const [isLoading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
fetch('https://gnikdroy.pythonanywhere.com/api/book')
.then((res) => res.json())
.then((data) => {
setData(data);
setLoading(false);
});
}, []);
return(
<div>
{data.results.map((book, index) => (
<div key={index}>
<h1>{book.title}</h1>
<Link href={`/reader/${book.id}`} passHref>
<h2>
{
book.resources.find(
({ type }) => type === 'application/epub+zip'
).uri
}
</h2>
</Link>
</div>
))}
</div>
)
searchPage.js
const router = useRouter();
const { name } = router.query;
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
fetch(`https://gnikdroy.pythonanywhere.com/api/book/?search=${name}`)
.then((res) => res.json())
.then((data) => {
setData(data);
setLoading(false);
console.log(data);
});
}, []);
return(
<div>
{data.results.map((book, index) => (
<div key={index}>
<h1>{book.title}</h1>
<Link href={`/reader/${book.id}`} passHref>
<h2>
{
book.resources.find(
({ type }) => type === 'application/epub+zip'
).uri
}
</h2>
</Link>
</div>
))}
</div>
)
我的 console.log 在 searchPage.js
中获取您的响应数据有时没有获取资源字段。
这就是 book.resources
可以未定义(或)为空的原因。
您可以轻松使用Optional Changing(?.)
替换:
{
book.resources?.find(
({ type }) => type === 'application/epub+zip'
)?.uri || ''
}
除了 Wu Woo 的回答,当考虑 React 如何渲染你的代码时,
首先将执行 return
,然后仅在页面加载时执行 useEffect
,因为 useEffect
依赖数组中没有值。
所以在您的场景中,您在初始页面加载时有 data = null。所以当渲染下面的代码时,因为 data = null data.results
不能使用 Arrays.map().
然后将执行 useEffect
并在其中设置 API 调用中的值 return 并将该值设置为数据。
为避免渲染未定义错误,您必须确保 data.results
不等于 null/undefined,并且当存在 data.results
时渲染您想要的内容。
您可以通过以下方式实现。
可选的链接运算符 (?.) 作为 Wu Woo 的回答,当引用或函数可能是
时就不会报上面的错误了undefined or null
时,它简化了通过连接对象访问值的过程。那么当book.resources
等于 null/undefined.仅当
data.results
和book.resources
有值时才渲染,否则不会像下面那样。// Here conditionally check whether there is value for data?.results and if so render this. {data?.results && data.results.map((book, index) => ( <div key={index}> <h1>{book.title}</h1> <Link href={`/reader/${book.id}`} passHref> <h2> {/* Here also conditionally check whether there is value for book?.resources and if so render this. */} { book?.resources && book.resources.find( ({ type }) => type === 'application/epub+zip' ).uri } </h2> </Link> </div> ))}