useQuery 有条件地渲染数据
useQuery to conditionally render data
我正在尝试使用 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>
错误发生是因为在某个时候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
更改时呈现。
我正在尝试使用 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>
错误发生是因为在某个时候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
更改时呈现。