react-query useMutation 不会更新 UI 上的新更改

问题描述 投票:0回答:1

我有一个 React 18 应用程序。我正在使用

@tanstack/react-query
,版本 5 进行状态管理。

首先,当我点击“喜欢”按钮时,我的用户界面没有改变。典型的行为应该是点赞数应该增加一个。

clicking like button does not update ui

其次,当我重新加载页面时,我的浏览器控制台中出现以下错误,并且我的浏览器视图为空白。

error on reload

不确定,我在这里做错了什么。

下面是我的代码:

App.jsx
文件:

import { useState } from "react";
import MenuBar from "./components/MenuBar";
import Notification from "./components/Notification";
import BlogsPage from "./pages/BlogsPage";
import LoginPage from "./pages/LoginPage";
import UsersPage from "./pages/UsersPage";
import { Route, Routes, useMatch } from "react-router-dom";
import User from "./components/User";
import { useQueryClient } from "@tanstack/react-query";
import Blog from "./components/Blog";

const App = () => {
  const queryClient = useQueryClient();
  const allBlogs = queryClient.getQueryData(['blogs']);
  const allUsers = queryClient.getQueryData(['users']);

  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");

  const userMatch = useMatch("/users/:id");
  console.log('userMatch', userMatch);
  const singleUserInfo = userMatch
    ? allUsers.find(user => user.id === userMatch.params.id)
    : null;
  console.log('singleUserInfo', singleUserInfo);

  const blogMatch = useMatch("/blogs/:id");
  console.log('blogMatch', blogMatch);
  const singleBlogInfo = blogMatch
    ? allBlogs.find(blog => blog.id === blogMatch.params.id)
    : null;
  console.log('singleBlogInfo', singleBlogInfo);

  return (
    <div>
      <h1>Blogs App</h1>

      <MenuBar setUsername={setUsername} setPassword={setPassword} />

      <Notification />

      <LoginPage 
        username={username} 
        password={password} 
        setUsername={setUsername} 
        setPassword={setPassword} 
      />

      <Routes>
        <Route path="/users/:id" element={<User user={singleUserInfo} />} />
        <Route path="/blogs/:id" element={<Blog blog={singleBlogInfo} />} />
        <Route path="/users" element={<UsersPage />} />
        <Route path="/" element={<BlogsPage />} />
      </Routes>
    </div>
  );
};

export default App;

Blog.jsx
文件:

import PropTypes from "prop-types";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useNotificationDispatch } from "../context/NotificationContext";
import blogService from "../services/blogs";
import { removeNotificationAfterFiveSeconds, setNotification } from "../helper/notificationSetOrRemove";
import { useUserValue } from "../context/UserContext";
import { Link } from "react-router-dom";

const Blog = ({ blog }) => {
  console.log('Blog.jsx', blog);

  const queryClient = useQueryClient();
  const notificationDispatch = useNotificationDispatch();
  const userLoggedIn = useUserValue();
  
  const updateBlogMutation = useMutation({
    mutationFn: blogService.updateBlog,
    // mutationFn: (blog) => blogService.updateBlog(blog),
    onSuccess: (updatedBlog) => {
      // queryClient.invalidateQueries('blogs');
      queryClient.invalidateQueries({ queryKey: ['blogs'] }, updatedBlog);
    },
    onError: (error, blogData) => {
      console.error(`UPDATE MUTATION ERROR: ${error.message}`);
      setNotification(notificationDispatch, `UPDATE MUTATION ERROR: Blog '${blogData.title}' was already removed from server`, true);
      removeNotificationAfterFiveSeconds(notificationDispatch);
    }
  });

  const handleIncreaseLikes = () => {
    updateBlogMutation.mutate({ ...blog, likes: blog.likes + 1 });
  };

  return (
    <div>
      <h1 data-testid="title">{blog.title}</h1>
      <h4 data-testid="author">Author: {blog.author}</h4>

      <div data-testid="url">
        <Link to={blog.url} target="_blank">{blog.url}</Link>
      </div>

      <div>
        <div>
          <div>
            <span data-testid="likes">Likes: {blog.likes}</span>
            <button onClick={handleIncreaseLikes} className="likeBtn">
              like
            </button>
          </div>

          <div data-testid="addedBy">Added by: {blog.user.name}</div>
        </div>
      </div>
    </div>
  );
};

Blog.propTypes = {
  blog: PropTypes.shape({
    id: PropTypes.string,
    title: PropTypes.string.isRequired,
    author: PropTypes.string.isRequired,
    url: PropTypes.string.isRequired,
    likes: PropTypes.number,
    user: PropTypes.shape({
      id: PropTypes.string.isRequired,
      name: PropTypes.string.isRequired,
      username: PropTypes.string.isRequired,
    }),
  }),
};

export default Blog;

/src/services/blogs.js
文件:

import axios from 'axios';
const baseUrl = '/api/blogs';

const updateBlog = async (updatedBlog) => {
  const response = await axios.put(`${baseUrl}/${updatedBlog.id}`, updatedBlog);
  return response.data;
};

export default { updateBlog };
javascript reactjs react-query tanstackreact-query
1个回答
0
投票

useQueryClient
不会对任何查询数据更改做出反应。标准方法是调用
useQuery
来检索任何数据(自动处理缓存)。

const allBlogs = useQuery({
    queryKey: ['blogs'],
    queryFn: () => {/* make request to get blog data*/}
}).data;
© www.soinside.com 2019 - 2024. All rights reserved.