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

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

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

ohfgkhjo

ohfgkhjo1#

你可以这么做

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

const [rerender, setRerender] = useState(false);

...
//And whenever you want to re-render, you can do this
setRerender(!rerender);

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

gopyfrb3

gopyfrb32#

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

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函数中设置它:

const [helper, setHelper] = useState(false);
    function forceUpdate(){
        setHelper(!helper);
    }

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

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

2ic8powd

2ic8powd4#

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

import React, { useState } from 'react';

//create your forceUpdate hook
function useForceUpdate(){
    const [value, setValue] = useState(0); // integer state
    return () => setValue(value => ++value); // update the state to force render
}

function MyComponent() {
    // call your hook here
    const forceUpdate = useForceUpdate();

    return (
        <div>
            {/*Clicking on the button will force to re-render like force update does */}
            <button onClick={forceUpdate}>
                Click to re-render
            </button>
        </div>
    );
}

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

ct3nt3jp

ct3nt3jp5#

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

<Element onSomethingHappen={
   ()=>{
   if(shouldComponentUpdate())
      this.forceUpdate();
}}/>

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

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

qyzbxkaa

qyzbxkaa6#

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

const TheComponentToBeRerendered = () => {
  const [key, setKey] = useState(0);

  const forceUpdate = () => {
    setKey(s => s + 1);
  };

  return (
    <TheFirstWrapperEvenAFragment
      key={`_a_key_for_force_update_${key}`}
    >
      ~ ~ ~
    </TheFirstWrapperEvenAFragment>
  );
};

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

相关问题