我有一个外部组件(可观察到的对象),我想在其上侦听更改。当对象被更新时,它发出更改事件,然后我想在检测到任何更改时重新呈现该组件。
使用顶级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 组件是否需要具有状态才能重新渲染?有没有一种方法可以在不更改状态的情况下强制组件按需更新?
在您的组件中,您可以调用this.forceUpdate()
强制重新渲染。
文档: https://facebook.github.io/react/docs/component-api.html
forceUpdate
因为它偏离了 React 的思维方式。 React 文档引用了一个可能使用forceUpdate
默认情况下,当组件的状态或道具更改时,组件将重新渲染。但是,如果这些隐式更改(例如,对象深处的数据发生更改而不更改对象本身),或者您的 render()方法依赖于其他一些数据,则可以通过调用告诉 React 它需要重新运行 render()强制性升级()。
但是,我想提出一个想法,即使对于深度嵌套的对象, forceUpdate
需要 forceUpdate。通过使用不可变的数据源,跟踪更改变得便宜。更改将始终导致一个新对象,因此我们只需要检查对该对象的引用是否已更改。您可以使用库Immutable JS在应用程序中实现不可变数据对象。
通常,您应该避免使用 forceUpdate(),而只能从 render()中的 this.props 和 this.state 中读取。这使您的组件 “纯净”,并使您的应用程序更加简单和高效。强制性升级()
更改要重新渲染的元素的键即可。通过状态在元素上设置关键道具,然后在要更新设置状态以拥有新关键时进行设置。
<Element key={this.state.key} />
然后发生更改,您重置了密钥
this.setState({ key: Math.random() });
我要注意,这将替换密钥正在更改的元素。例如,当您有一个文件输入字段要在上载图像后重设时,此操作可能会有用。
尽管对 OP 问题的真正答案是forceUpdate()
我发现这种解决方案在不同情况下很有用。我还想指出,如果您发现自己使用forceUpdate
,则可能需要查看代码,看看是否还有另一种处理方法。
注意 1-9-2019:
上面的(更改密钥)将完全替换该元素。如果您发现自己更新了密钥以进行更改,则可能是代码中的其他地方出现了问题。在 key 中使用Math.random()
将在每个渲染器中重新创建元素。我不建议像这样更新密钥,因为 react 使用密钥来确定重新渲染事物的最佳方法。
实际上, forceUpdate()
是唯一正确的解决方案,因为shouldComponentUpdate()
实现了附加逻辑,或者仅返回false
setState()
可能不会触发重新渲染。
调用
forceUpdate()
将导致在组件上render()
shouldComponentUpdate()
。更多的...
shouldComponentUpdate()
实现了条件渲染逻辑,否则setState()
将始终触发重新渲染。更多的...
forceUpdate()
可以从组件内调用this.forceUpdate()