你可以强制一个React组件重新渲染而不用调用setState?
我有一个外部(对组件),我想要听取更改的可观察对象。 当对象更新时,它会发出更改事件,然后我想在检测到任何更改时重新渲染组件。
有了顶层的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> ) } }
点击button内部调用this.render()
,但这不是真正导致渲染发生的事情(您可以看到这是实际的,因为由{Math.random()}
创build的文本不会改变)。 但是,如果我简单地调用this.setState()
而不是this.render()
,它工作正常。
所以我想我的问题是: React组件需要有状态才能重新渲染? 有没有办法强制组件按需更新而不改变状态?
在你的组件中,你可以调用this.forceUpdate()
强制重新渲染。
文档: https : //facebook.github.io/react/docs/component-api.html
应该避免forceUpdate
因为它偏离了React思维模式。 React文档引用了forceUpdate
可以使用的一个例子:
默认情况下,当组件的状态或者道具改变时,你的组件将重新渲染。 但是,如果这些变化隐含地变化(例如:对象内部的深度数据改变而不改变对象本身),或者如果render()方法依赖于其他数据,则可以通过调用来告诉React它需要重新运行render强制性升级()。
不过,我想提出一个想法,即使深度嵌套的对象, forceUpdate
是不必要的。 通过使用不可变的数据源跟踪变化变得便宜; 一个变化总是会导致一个新的对象,所以我们只需要检查对象的引用是否已经改变了。 您可以使用库Immutable JS将不可变数据对象实现到您的应用程序中。
通常你应该尽量避免使用forceUpdate(),只能从render()中的this.props和this.state中读取。 这使得你的组件“纯”,你的应用程序更简单,更高效。 https://facebook.github.io/react/docs/component-api.html#forceupdate
改变你想要重新渲染的元素的键将工作。 通过状态设置你的元素的关键支柱,然后当你想更新设置状态有一个新的关键。
<Element key={this.state.key} />
然后发生更改,并重置密钥
this.setState({ key: Math.random() });
我想要注意的是,这将取代密钥正在改变的元素。 例如,当你有一个文件input域,你想在图像上传后重置。
虽然OP的问题的真正答案是forceUpdate()
我发现这个解决scheme在不同情况下有帮助。 我还想指出,如果你发现自己使用forceUpdate
你可能想要检查你的代码,看看是否有另一种方式来做事情。
实际上, forceUpdate()
是唯一正确的解决scheme,因为如果在shouldComponentUpdate()
实现了额外的逻辑,或者只是返回false
, setState()
可能不会触发重新渲染。
强制性升级()
调用
forceUpdate()
将导致在组件上调用render()
,跳过shouldComponentUpdate()
。 更多…
的setState()
setState()
将始终触发重新呈现,除非在shouldComponentUpdate()
实现了条件呈现逻辑。 更多…
可以通过this.forceUpdate()
从组件内部调用this.forceUpdate()
当你想要两个React组件进行通信时,它们不受关系(父子)的约束,build议使用Flux或类似的体系结构。
你想要做的是听监视组件存储的变化,它保存模型及其接口,并保存导致渲染在MyComponent
作为state
改变的数据。 当商店推送新数据时,您将更改组件的状态,这会自动触发渲染。
应始终避免forceUpdate()
。 从文档:
通常你应该尽量避免使用forceUpdate(),只能从render()中的this.props和this.state中读取。 这使得您的应用程序更简单,更高效
所以我想我的问题是:React组件需要有状态才能重新渲染? 有没有办法强制组件按需更新而不改变状态?
其他答案试图说明你如何能,但重点是你不应该 。 即使是改变钥匙的拙劣的解决办法也没有意义。 React的力量放弃了手动pipe理什么时候应该呈现的控制,而只是关心自己应该如何在input上绘制图表。 然后提供inputstream。
如果你需要手动强制重新渲染,你几乎肯定没有做正确的事情。
我通过下面的方法避免了forceUpdate
错误的方式 :不要使用索引作为关键
this.state.rows.map((item, index) => <MyComponent cell={item} key={index} /> )
正确的方法 :使用数据ID作为关键,它可以是一些GUID等
this.state.rows.map((item, index) => <MyComponent item={item} key={item.id} /> )
所以通过做这样的代码改进你的组件将是唯一的,并自然呈现
你可以通过以下几种方法来完成:
1.使用forceUpdate()
方法:
使用forceUpdate()
方法时可能会发生一些故障。 一个例子是,它忽略了shouldComponentUpdate()
方法,并将重新呈现视图,无论shouldComponentUpdate()
是否返回false。 因为这个使用forceUpdate()应尽可能避免。
2.将this.state传递给setState()
方法
下面这行代码克服了前面例子中的问题:
this.setState(this.state);
真的,这一切都是用当前触发重新渲染的状态覆盖当前状态。 这仍然不一定是最好的办法,但它克服了使用forceUpdate()方法可能遇到的一些小问题。