小编典典

你可以在不调用 setState 的情况下强制 React 组件重新渲染吗?

all

我有一个外部(组件)的可观察对象,我想监听它的变化。当对象更新时,它会发出更改事件,然后我想在检测到任何更改时重新渲染组件。

使用顶层React.render这是可能的,但是在组件中它不起作用(这是有道理的,因为该render方法只返回一个对象)。

这是一个代码示例:

export default class MyComponent extends React.Component {

  handleButtonClick() {
    this.render();
  }

  render() {
    return (
      <div>
        {Math.random()}
        <button onClick={this.handleButtonClick.bind(this)}>
          Click me
        </button>
      </div>
    )
  }
}

单击按钮在内部调用this.render(),但这并不是真正导致渲染发生的原因(您可以在实际中看到这一点,因为由创建的文本{Math.random()}不会更改)。但是,如果我只是调用this.setState()而不是this.render(),它工作正常。

所以我想我的问题是: React 组件 是否需要 有状态才能重新渲染?有没有办法强制组件按需更新而不改变状态?


阅读 106

收藏
2022-02-28

共1个答案

小编典典

在类组件中,您可以调用this.forceUpdate()强制重新渲染。

文档:https ://facebook.github.io/react/docs/component-
api.html

在函数组件中,没有等效的forceUpdate,但您可以设计一种使用useStateReact hooks)强制更新的方法。

您现在可以调用useState()您的函数组件。

useState()将返回一个包含两件事的数组:

  1. 一个值,表示当前状态。
  2. 它的二传手。使用它来更新值。

通过它的设置器更新值将强制您的函数组件重新渲染
就像这样forceUpdate做:

import React, { useState } from 'react';

//create your forceUpdate hook
function useForceUpdate(){
    const [value, setValue] = useState(0); // integer state
    return () => setValue(value => value + 1); // 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>
    );
}

你可以在这里找到一个演示

上面的组件使用了一个自定义的钩子函数 ( useForceUpdate),它使用了反应React hooks子useState。它增加组件的状态值,从而告诉 React 重新渲染组件。

编辑

在此答案的旧版本中,该片段使用了一个布尔值,并将其切换为forceUpdate(). 现在我已经编辑了我的答案,该片段使用数字而不是布尔值。

为什么 ?(你会问我)

因为一旦发生在我身上,我forceUpdate()随后从 2 个不同的事件中被调用了两次,因此它将布尔值重置为其原始状态,并且组件从未呈现。

这是因为在useState‘s setter ( setValuehere) 中,React将先前的状态与新的状态进行比较,仅当状态不同时才渲染。

2022-02-28