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

处于React状态的对象的快速刷新+更新功能实现

如何解决处于React状态的对象的快速刷新+更新功能实现

假设我有一个React应用,该应用具有内部状态,其中我存储了类似对象

  const [car,setCar] = useState(new Car());

假设我的班级Car如下所示:

class Car {
  constructor(brand) {
    this.carname = brand;
  }

  present() {
    return "I have a " + this.carname;
  }
}

运行和调试应用程序时,我可以将Car对象保存到状态中,也可以检索它并调用present()。

现在,当我对present()函数进行更改时,例如

  present() {
    return "I have a " + this.carname + " and it is shiny";
  }

然后由于快速刷新,我的应用程序被刷新。但不幸的是,由于该对象已经存储在状态中,因此它将无法接收功能实现的更新。

有没有一种方法可以更改代码,以便使用快速刷新功能也可以为处于React状态的对象更新函数实现?

我尝试通过原型更新方法,但是它也没有用。

解决方法

根据设计,“快速刷新”将尽可能保留状态。但是useEffect将始终在快速刷新期间更新,而不管依赖项数组中的内容如何。只要提供一个空的依赖关系数组,就可以在useEffect内使用setState来更改快速刷新之间的状态。

 const [car,setCar] = useState(new Car());

 useEffect(() => {
    setCar(new Car());
  },[])

请记住,useEffect仅在第一个渲染之后运行,因此您需要在useState挂钩参数中保留默认状态new Car(),以防止发生任何未定义的错误。

,

这实际上有点棘手,因为您要实现的目标在某种程度上与react围绕不可变的设计背道而驰。使用def parameterize(search_string,kw): expanded = search_string.split(maxsplit=14) sql = "" for word in expanded: sql = "{sql}{cond_keyword} ? ".format(sql=sql,cond_keyword=kw if sql and len(expanded) > 1 else "",word=word ) sql = "{sql}".format(sql=sql.lstrip().rstrip()) qargs = tuple(expanded) return sql,qargs def ka_search(search_str): and_cond = parameterize(search_str,"AND") near_cond = parameterize(search_str,"NEAR") near_params = near_cond[0] and_params = and_cond[0] # build a final tuple of all parameters in order of the individual sub-queries that are union-ed together args1 = list(and_cond[1]) args2 = [search_str] args3 = list(near_cond[1]) args = args1 + args2 + args3 + args2 try: cursor = db_connect() cursor.execute(""" SELECT Title,CONCAT(RTRIM(LEFT(Bodytext,150)),'...') as BodyText,Keywords,RecId,rank,CONCAT('/kb/',RecId) AS Link FROM KnowledgeArticle AS FT_TBL INNER JOIN CONTAINSTABLE(KnowledgeArticle,(Title,keywords),{and_params}) AS KEY_TBL ON FT_TBL.RecID = KEY_TBL.[KEY] WHERE VisibleToCustomerPortal = 'true' AND Status = 'Published' UNION SELECT Title,RecId) AS Link FROM KnowledgeArticle AS FT_TBL INNER JOIN FREETEXTTABLE(KnowledgeArticle,Title,?) AS KEY_TBL ON FT_TBL.RecID = KEY_TBL.[KEY] WHERE VisibleToCustomerPortal = 'true' AND Status = 'Published' UNION SELECT Title,RecId) AS Link FROM KnowledgeArticle AS FT_TBL INNER JOIN CONTAINSTABLE(KnowledgeArticle,{near_params}) AS KEY_TBL ON FT_TBL.RecID = KEY_TBL.[KEY] WHERE VisibleToCustomerPortal = 'true' AND Status = 'Published' SELECT Title,Bodytext,?) AS KEY_TBL ON FT_TBL.RecID = KEY_TBL.[KEY] WHERE VisibleToCustomerPortal = 'true' AND Status = 'Published' ORDER BY rank DESC """.format(and_params=and_params,near_params=near_params),args) 可以轻松地直接更改类方法并将其分配给现有实例。

这将替换原始汽车实例的原型并更改方法的实现。如您所说,这是行不通的,因为对对象进行突变不会触发重新渲染。

useState使用Object.setPrototypeOf(car,Car.prototype)比较对象,在这种情况下,由于两个对象具有相同的引用,因此不会触发重新渲染。

为了Object.is(),您需要将具有新原型和现有实例的确切属性的新对象传递到Object.is()。使用基本扩展运算符setCar(){..car}无法做到这一点,因为这些方法仅复制对象自身的可枚举属性。

您可以改为使用以下命令创建具有与新原型Object.assign({},car)完全相同的属性的新对象。

可以将其放置在useEffect内,它将在每次更改原始Car类时运行

setCar(Object.assign(Object.create(Car.prototype),car))

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

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?