redux 如何强制更新功能组件?

o75abkj4  于 2023-11-19  发布在  其他
关注(0)|答案(6)|浏览(177)

我正在学习redux,想知道useSelector如何更新组件,因为组件没有自己的状态。
我知道useSelector()将组件订阅到存储,当存储更新时,组件也会更新。
类组件有this.forceUpdate(),但函数组件没有。
如何强制更新功能组件?

ohfgkhjo

ohfgkhjo1#

你可以这么做

添加可以更改的虚拟状态,以可靠地启动重新渲染。

  1. const [rerender, setRerender] = useState(false);
  2. ...
  3. //And whenever you want to re-render, you can do this
  4. setRerender(!rerender);

字符串
这将重新呈现组件,因为组件总是在状态改变时重新呈现

gopyfrb3

gopyfrb32#

react-redux包依赖于react/react-dom的渲染引擎来触发使用useSelector钩子的给定组件的重新渲染。
如果你看一下useSelector的源代码,你可以注意到useReducer的使用:

  1. const [, forceRender] = useReducer((s) => s + 1, 0)

字符串
正如名字(forceRender)所暗示的,redux使用它来触发react重新渲染。

  • 使用react-reduxv8,此机制的实现发生了变化,但仍然依赖于react-hooks进行重新渲染。

如果你想知道React是如何处理re-renders的,可以看看this excellent SO answer。它提供了一个很好的入口,介绍了react-hooks如何与调用组件相关联的实现细节。
我不重复瑞安在这里,但总结一下
渲染器保持对当前渲染的组件的引用。在此渲染期间执行的所有钩子(无论它们在自定义钩子中嵌套有多深)最终都属于此组件。* 因此,useReducer与您调用useSelector的组件相关联。*
useReducer的dispatch函数触发了该组件的重新渲染(React调用类组件的render()方法或执行功能组件的函数体)。
如果您想知道react-redux如何确定何时应该强制重新呈现(通过利用useReducer),请再看一下useSelector的源代码。
Redux使用订阅者模式来获取状态更新的通知。如果redux的根状态被更新,会发生以下情况:
1.应用程序中的useSelector钩子重新运行其选择器函数
1.这个重新选择的状态与先前选择的状态进行比较(默认情况下通过===比较)。* useSelector的第二个参数可以是一个比较函数,以更改此行为 *
1.如果重新选择的状态与先前选择的状态不同,则通过useReducer钩子触发重新呈现。
订阅者模式非常类似于react,但可能有助于保存许多重新呈现。与重新呈现相比,调用几个useSelector钩子的成本很低。

展开查看全部
0lvr5msh

0lvr5msh3#

继续其他答案,为了保持代码整洁,你可以创建一个虚拟状态,然后在你自己的forceUpdate函数中设置它:

  1. const [helper, setHelper] = useState(false);
  2. function forceUpdate(){
  3. setHelper(!helper);
  4. }

字符串
现在你可以在剩下的代码中调用forceUpdate()

  1. <div onClick={() => forceUpdate()} />

2ic8powd

2ic8powd4#

首先,我想提一下,当你使用usebookhook的时候,你不需要强制更新。只要所选的状态值被更新,重新呈现就会自动发生。
但是如果你需要强制更新功能组件,你可以使用这种方法。

  1. import React, { useState } from 'react';
  2. //create your forceUpdate hook
  3. function useForceUpdate(){
  4. const [value, setValue] = useState(0); // integer state
  5. return () => setValue(value => ++value); // update the state to force render
  6. }
  7. function MyComponent() {
  8. // call your hook here
  9. const forceUpdate = useForceUpdate();
  10. return (
  11. <div>
  12. {/*Clicking on the button will force to re-render like force update does */}
  13. <button onClick={forceUpdate}>
  14. Click to re-render
  15. </button>
  16. </div>
  17. );
  18. }

字符串
我强烈建议避免使用这种黑客,在99%的问题,你可以解决他们没有强制更新.但在任何情况下,这是很好的知道,有这样的可能性在功能组件存在太.

展开查看全部
ct3nt3jp

ct3nt3jp5#

也许这样的东西可以帮助你:
在一个类组件中,你可以传递一个像下面这样的属性。

  1. <Element onSomethingHappen={
  2. ()=>{
  3. if(shouldComponentUpdate())
  4. this.forceUpdate();
  5. }}/>

字符串
在函数组件中,你可以像这样调用更新器:

  1. function FunctionComponent(props){
  2. //When you need it you can update like this one...
  3. props.onSomethingHappen();
  4. // Here you are ;) let me know if this helps you
  5. }

展开查看全部
qyzbxkaa

qyzbxkaa6#

到目前为止,所有答案都是可以接受的,还有另一种选择,使用key prop如下:

  1. const TheComponentToBeRerendered = () => {
  2. const [key, setKey] = useState(0);
  3. const forceUpdate = () => {
  4. setKey(s => s + 1);
  5. };
  6. return (
  7. <TheFirstWrapperEvenAFragment
  8. key={`_a_key_for_force_update_${key}`}
  9. >
  10. ~ ~ ~
  11. </TheFirstWrapperEvenAFragment>
  12. );
  13. };

字符串
key prop确实存在于所有组件中,通过更改它,可以保证强制更新。因此,在这里,通过调用forceUpdate函数,强制更新将发生。

展开查看全部

相关问题