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

使用顶级React。渲染这是可能的,但在组件中它不起作用(这是有意义的,因为渲染方法只返回一个对象)。

下面是一个代码示例:

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组件需要有状态才能渲染吗?是否有一种方法可以在不改变状态的情况下强制组件按需更新?


当前回答

所以我想我的问题是:React组件需要有状态吗 要重新渲染?是否有一种方法强制组件更新 不改变状态的需求?

其他答案试图说明你可以这样做,但关键是你不应该这样做。即使是改变密钥这种俗气的解决方案也没有抓住重点。React的强大之处在于放弃手动管理内容何时应该呈现的控制,而只是关注内容应该如何映射到输入上。然后供给输入流。

如果您需要手动强制重新渲染,那么几乎可以肯定您做得不对。

其他回答

为了完成你所描述的,请尝试this.forceUpdate()。

你可以有几种方法:

1. 使用forceUpdate()方法:

使用forceUpdate()方法时可能会出现一些故障。一个例子是它忽略shouldComponentUpdate()方法,并将重新呈现视图,而不管shouldComponentUpdate()是否返回false。因此,应该尽可能避免使用forceUpdate()。

2. 通过这个。状态转换为setState()方法

下面这行代码克服了前面例子中的问题:

this.setState(this.state);

实际上,所有这些都是用触发重新渲染的当前状态覆盖当前状态。这仍然不一定是最好的方法,但它确实克服了使用forceUpdate()方法时可能遇到的一些故障。

为了完整性,你也可以在功能组件中实现:

const [, updateState] = useState();
const forceUpdate = useCallback(() => updateState({}), []);
// ...
forceUpdate();

或者,作为一个可重复使用的钩子:

const useForceUpdate = () => {
  const [, updateState] = useState();
  return useCallback(() => updateState({}), []);
}
// const forceUpdate = useForceUpdate();

参见:https://stackoverflow.com/a/53215514/2692307

请注意,使用强制更新机制仍然是不好的做法,因为它违背了反应的心态,所以如果可能的话仍然应该避免。

我发现最好避免使用forceUpdate()。强制重新呈现的一种方法是在临时外部变量上添加render()依赖项,并在需要时更改该变量的值。

下面是一个代码示例:

class Example extends Component{
   constructor(props){
      this.state = {temp:0};

      this.forceChange = this.forceChange.bind(this);
   }

   forceChange(){
      this.setState(prevState => ({
          temp: prevState.temp++
      })); 
   }

   render(){
      return(
         <div>{this.state.temp &&
             <div>
                  ... add code here ...
             </div>}
         </div>
      )
   }
}

当你需要强制重新渲染时,调用this.forceChange()。

实际上,forceUpdate()是唯一正确的解决方案,因为如果在shouldComponentUpdate()中实现了额外的逻辑,或者当它只是返回false时,setState()可能不会触发重新呈现。

强制更新()

调用forceUpdate()将导致在组件上调用render(),跳过shouldComponentUpdate()。更多…

设置状态()

setState()总是会触发重新呈现,除非在shouldComponentUpdate()中实现了条件呈现逻辑。更多…

forceUpdate()可以通过this.forceUpdate()从组件中调用

钩子:如何在React中使用钩子强制组件重新渲染?

顺便说一句:你是在改变状态还是你的嵌套属性不传播?

如何在React中更新嵌套的状态属性 沙盒