我正在尝试使用useQuery
来从数据库中复制数据GET
,然后在REACT组件中呈现数据,但是我一直从JSX中收到长度不确定的错误。有人可以告诉我我对useQuery
的使用是否不正确吗?
const SavedBooks = () => {
const [userData, setUserData] = useState({});
const { loading, data } = useQuery(GET_ME);
console.log(loading)
console.log(data?.me)
if (loading) {
return <h2>LOADING...</h2>
} else {
setUserData(data?.me);
}
// create function that accepts the book's mongo _id value as param and deletes the book from the database
const handleDeleteBook = async (bookId) => {
const token = Auth.loggedIn() ? Auth.getToken() : null;
if (!token) {
return false;
}
try {
const response = await deleteBook(bookId, token);
if (!response.ok) {
throw new Error('something went wrong!');
}
const updatedUser = await response.json();
setUserData(updatedUser);
// upon success, remove book's id from localStorage
removeBookId(bookId);
} catch (err) {
console.error(err);
}
};
return (
<>
<Jumbotron fluid className='text-light bg-dark'>
<Container>
<h1>Viewing saved books!</h1>
</Container>
</Jumbotron>
<Container>
<h2>
{userData?.savedBooks.length
? `Viewing ${userData.savedBooks.length} saved ${userData.savedBooks.length === 1 ? 'book' : 'books'}:`
: 'You have no saved books!'}
</h2>
<CardColumns>
{userData?.savedBooks.map((book) => {
return (
<Card key={book.bookId} border='dark'>
{book.image ? <Card.Img src={book.image} alt={`The cover for ${book.title}`} variant='top' /> : null}
<Card.Body>
<Card.Title>{book.title}</Card.Title>
<p className='small'>Authors: {book.authors}</p>
<Card.Text>{book.description}</Card.Text>
<Button className='btn-block btn-danger' onClick={() => handleDeleteBook(book.bookId)}>
Delete this Book!
</Button>
</Card.Body>
</Card>
)
})}
</CardColumns>
</Container>
</>
);
};
数据最终将最终记录在控制台中,但它不会阻止我的JSX继续发送,因此我在该区域周围遇到了 Cannot read property 'length' of undefined
:
<h2>
{userData?.savedBooks.length
? `Viewing ${userData.savedBooks.length} saved ${userData.savedBooks.length === 1 ? 'book' : 'books'}:`
: 'You have no saved books!'}
</h2>
答案 0 :(得分:1)
发生错误是因为在某个时刻savedBooks
= undifiend
因此,您需要做的就是检查它是否存在,只需添加另一个?
userData?.savedBooks?.length
<h2>
{loading ? 'LOADING...' :
userData?.savedBooks?.length ?
`Viewing ${userData.savedBooks.length} saved ${userData.savedBooks.length === 1 ? 'book' : 'books'}:`
: 'You have no saved books!'}
</h2>
代码中也可能会引起一些问题
您不应该在功能组件主体内部直接使用setUserData
,否则会导致不必要的重新渲染或进入无限渲染循环。
我建议做这样的事情:
useEffect(() => {
setUserData(data?.me);
}, [data]);
这将使组件仅在data
更改时呈现。