能在不调用setState的情况下强制React组件进行渲染吗?

Number of views 50

我有一个外部(相对于组件而言)的、可观察的对象,我想监听它上面的变化。当该对象更新时,它会触发Change事件,然后我希望在监测到任何变化时重新渲染组件。

使用Top的 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 组件是否需要有绑定状态并且状态改变后才能重新渲染?有没有办法在不改变状态的情况下强制组件按需更新?
1 Answers

你不能直接调用 render 方法来强制 React 组件重新渲染。render 方法只是组件生命周期的一部分,用于创建虚拟 DOM 树,但它并不会触发组件的实际重新渲染。组件的重新渲染是由 React 内部机制控制的,通常是基于状态(state)或属性(props)的变化。

如果你希望在没有状态或属性变化的情况下强制组件重新渲染,通常的做法是通过状态或属性的变化来间接地实现这一点。你可以设置一个状态变量,每次外部对象发生变化时更新这个状态变量,从而触发组件的重新渲染。

以下是一个示例代码,展示了如何实现这一点:

import React, { Component } from 'react';

export default class MyComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      randomValue: Math.random()
    };
  }

  componentDidMount() {
    // 假设你有一个外部可观察的对象,这里我们用一个简单的定时器模拟
    setInterval(() => {
      this.setState({ randomValue: Math.random() });
    }, 1000); // 每秒更新一次状态
  }

  handleButtonClick() {
    this.setState({ randomValue: Math.random() });
  }

  render() {
    return (
      <div>
        {this.state.randomValue}
        <button onClick={() => this.handleButtonClick()}>
          Click me
        </button>
      </div>
    );
  }
}

在这个示例中,我们通过 setInterval 模拟了外部对象的变化,并在每次变化时更新组件的状态,从而触发重新渲染。

如果你确实需要监听外部对象的变化并触发重新渲染,你可以考虑使用 useEffect 钩子和 useState 来管理状态。例如:

import React, { useState, useEffect } from 'react';

export default function MyComponent(props) {
  const [randomValue, setRandomValue] = useState(Math.random());

  useEffect(() => {
    // 假设你有一个外部可观察的对象,这里我们用一个简单的定时器模拟
    const intervalId = setInterval(() => {
      setRandomValue(Math.random());
    }, 1000); // 每秒更新一次状态

    // 清理副作用
    return () => clearInterval(intervalId);
  }, []);

  const handleButtonClick = () => {
    setRandomValue(Math.random());
  };

  return (
    <div>
      {randomValue}
      <button onClick={handleButtonClick}>
        Click me
      </button>
    </div>
  );
}

在这个示例中,我们使用 useState 来管理状态,并使用 useEffect 来监听外部对象的变化。每次外部对象发生变化时,我们更新状态,从而触发组件的重新渲染。