导航到另一页时,next / link丢失状态

如何解决导航到另一页时,next / link丢失状态

我正在开发 Next.js应用程序。出于这个问题的目的,我在应用程序中有两个页面: BooksPage (列出所有书籍)和 BookPage (用于呈现书籍的详细信息)。在组件方面,我有一个<Books />组件,它为我的图书馆数据库中的每本书提供了一个<Book />组件。

这是我的组成部分:

Books.js

function Books({ books }) {
  return (
    <>
      {books.map(book => (
        <Book key={book.id} book={book} />
      ))}
    </>
  );
}

Book.js

class Book extends React.Component {
  constructor(props,context) {
    super(props,context);
    this.state = { liked: false };
  }

  like = () => {
    this.setState({ liked: this.state.liked ? false : true })
  };

  render() {
    return (
      <>
        <Link href={`/books/${book.slug}`}>
          <a>{book.title}</a>
        </Link>

        <Button onClick={this.like}>
          <LikeIcon
            className={this.state.liked ? "text-success" : "text-dark"}
          />
        </Button>
      </>
    );
  }
}

问题:

说我在 BooksPage 页面上。当我单击<Book />的“赞”按钮时,图标颜色在前端正确切换,并且在后端成功添加或删除了类似颜色。当我刷新 BooksPage 时,所有状态都保持不变。

当我喜欢 BooksPage 上的内容,然后立即导航到 BookPage 而不使用next / link刷新时,就会出现问题。那里的“赞”按钮未始终切换,并且 BooksPage 的状态丢失。请注意,如果我硬刷新页面,一切都会恢复正常。

慢速解决方案:请勿使用next / link。

替换

<Link href={`/books/${book.slug}`}>
  <a>{book.title}</a>
</Link>

使用

<a href={`/books/${book.slug}`}>{book.title}</a>

快速解决方案:继续使用下一个/链接吗?

导航到另一条预渲染的路线时,是否可以使用next / link并保持状态?

解决方法

您需要使用Model.refresh_from_db(...)--(Django Doc)方法来 从数据库中检索更新的值

class DeleteLikeView(APIView):

    def post(self,request,book):
        book = get_object_or_404(Book,id=book)
        print(book.num_of_likes)
        like = Like.objects.get(user=request.user,book=book)
        like.delete()

        book.refresh_from_db()  # here is the update
        
        print(book.num_of_likes)  # You will get the updated value
        return ...
,

TLDR:每当需要更改按钮时,API都必须更改数据,并且必须更新最接近父级的本地状态以更新button的外观。 API将控制本地状态的各个方面。除非API请求成功,否则您无法更新本地状态。因此,客户端和API始终为1:1。

Book.js 中的Button组件应与API数据分开维护其自身状态;相反,无论您从API那里获取book数据,它也应该控制按钮的状态(及其外观)。为什么?因为使用当前方法,API请求可能会失败,但是客户端仍将更新。结果,API和客户端可能不再是1:1(客户端显示喜欢,但API仍然显示不喜欢/不喜欢)。

在实践中,您将有一个充当状态管理器的父容器。它获取所有相关数据,处理数据更新,并使用 stateless 子组件显示结果。每当需要更新子组件时(例如,通过按下按钮显示“喜欢”或“不喜欢”按钮),它都必须首先发出API请求以更改数据,然后API必须以相关数据响应更新孩子使用的状态:

enter image description here

或者,如果该组件是可重用的,那么您将有条件地使用this.props.book(来自父容器)来呈现它,或者子组件必须从API请求数据以更新其自身的本地{{1 }}。与上图相同,API请求控制状态更改的所有方面:

enter image description here

还有另一种与上图相同的方法,但是它使用子级本地状态,而不管父级状态如何。此子状态将仅通过其自己的类方法进行更新。这带来了更多的复杂性,因为您必须确保任何父状态更改不会用陈旧的数据重新呈现子组件。最终,哪种方法取决于您。

附带说明:由于 不会呈现页面,也不会尝试内部页面导航。相反,它们提供了可重复使用的组件,这些组件可以被一个或多个NextJS项目页面或组件使用。

,

以某种方式通过API传递书籍的liked属性。然后,将该道具从Books组件传递到Book组件。

向您的图书组件添加componentDidUpdate()方法。

class Book extends React.Component {
  constructor(props,context) {
    super(props,context);
    this.state = { liked: this.props.liked };
  }

  componentDidUpdate(prevProps) {
    if (this.props.liked !== prevProps.liked) {
      this.setState({
        liked: this.props.liked,});
    }
  }

  like = () => {
    this.setState({ liked: !this.state.liked })
  };

  render() {
    return (
      <>
        <Link href={`/books/${book.slug}`}>
          <a>{book.title}</a>
        </Link>

        <Button onClick={this.like}>
          <LikeIcon
            className={this.state.liked ? "text-success" : "text-dark"}
          />
        </Button>
      </>
    );
  }
}
,

在DeleteLikeView类中,您获得书本对象。它从数据库检索并保存在book变量中。 当您删除类似对象的对象时,数据库中的num_of_likes属性已更新,但您的变量仍包含先前的对象。在like.delete()命令之后,您应该再次获取对象并打印num_of_likes att。符合您的预期。

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

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res