reactjs - ข้อผิดพลาด: คุณสมบัติ 'title' ไม่มีอยู่ในประเภท 'never' แต่ฉันเห็นบันทึกในเบราว์เซอร์
ฉันได้รับข้อผิดพลาด:
คุณสมบัติ 'title' ไม่มีอยู่ในประเภท 'never'. ..... console.log(blog.title);
แต่ที่คอนโซลของเบราว์เซอร์ฉันสามารถเห็น "blog.title"
นี่คือภาพหน้าจอจากเบราว์เซอร์
ในไฟล์นี้ฉันใช้ console.log และได้รับข้อผิดพลาด:
const BlogDetails = () => {
const { id } = useParams<{ id: string }>();
const {
data: blog,
error,
isPending,
} = useFetch("http://localhost:8500/blogs/" + id);
console.log(blog&& blog.title);
return (
<div className="blog-details">
{isPending && <div>loading...</div>}
{error && <div>{error}</div>}
{blog && (
<article>
<h2>BlogDetails</h2>
</article>
)}
</div>
);
};
export default BlogDetails;
ฉันใช้ฮุคที่กำหนดเองเพื่อดึงข้อมูล:
import { useState, useEffect } from "react";
const useFetch = (url: string) => {
const [data, setData] = useState(null);
const [isPending, setIsPending] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const abortCont = new AbortController();
setTimeout(() => {
fetch(url, { signal: abortCont.signal })
.then((res) => {
if (!res.ok) {
throw Error("could not fetch the data for that resource");
}
return res.json();
})
.then((data) => {
setIsPending(false);
setData(data);
setError(null);
})
.catch((err) => {
if (err.name === "AbortError") {
console.log("fetch aborted");
} else {
setIsPending(false);
setError(err.message);
}
});
}, 1000);
return () => abortCont.abort();
}, [url]);
return { data, isPending, error };
};
export default useFetch;
คำตอบ #1
Typescript ไม่สามารถอนุมานชนิดข้อมูลจากการเรียก API ได้ ดังนั้นคุณจะต้องระบุชนิดข้อมูลเหล่านั้นอย่างชัดเจน
อย่างไรก็ตาม เนื่องจาก useFetch เป็นฟังก์ชันแบบทั่วไป คุณจะต้องเพิ่มประเภทที่เหมาะสมกับการเรียกใช้งาน และส่งมันไปยัง useState ภายใน นอกจากนี้ ค่าตั้งต้นของ useState คือ null ดังนั้นเราควรพิจารณาสิ่งนั้นด้วย
เราสามารถเพิ่มชนิดทั่วไปเพื่อ useFetch - <T> และพิมพ์ useState<T | null>() เพื่ออนุญาตประเภทข้อมูลที่ต้องการ และ null:
export const useFetch = <T>(url: string) => {
const [data, setData] = useState<T | null>(null);
ในการใช้งาน คุณจะต้องส่งประเภทที่ชัดเจนไปยัง useFetch ตัวอย่างเช่น:
interface Data {
title: string;
body: string;
author: string;
id: number;
}
const { data: blog, error, isPending } = useFetch<Data>(
'http://localhost:8500/blogs/' + id
);
console.log(blog && blog.title); // or just console.log(blog?.title) with optional chaining
ทุกครั้งที่คุณเรียก useFetch คุณควรระบุประเภทข้อมูลที่เหมาะกับการตอบสนองปัจจุบัน ตัวอย่างเช่น:
useFetch<string[]>( // the result is an array of strings
useFetch<Data[]>( // the result is an array of data objects
useFetch<number>( // the result is a number
