微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

useQuery有条件地呈现数据

如何解决useQuery有条件地呈现数据

我正在尝试使用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更改时呈现。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。