我有一个外部(对组件),可观察对象,我想听取更改 . 当对象更新时,它会发出更改事件,然后我想在检测到任何更改时重新呈现组件 .
使用顶级 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()
,它可以正常工作 .
So I guess my question is: 做反应组件需要有状态才能重新渲染吗?有没有办法强制组件按需更新而不改变状态?
15 回答
其他答案试图说明你怎么做,但重点是你不应该 . 甚至改变密钥的黑客解决方案也忽略了这一点 . React的力量放弃了控制手动管理什么东西应该渲染,而只是关于你自己应该如何映射输入 . 然后提供输入流 .
如果你需要手动强制重新渲染,你几乎肯定没有做正确的事情 .
另一种方法是调用
setState
, AND 保存状态:this.setState(prevState=>({...prevState}));
我发现最好避免使用forceUpdate() . 强制重新渲染的一种方法是在临时外部变量上添加render()的依赖关系,并在需要时更改该变量的值 .
这是一个代码示例:
需要强制重新渲染时调用this.forceChange() .
没有州担心重新渲染
当我开始使用反应时,我正在将我的数据存储在状态中,我必须这样做才能进行渲染 . 那是非常错误的 . 事实证明,如果你推出一些简单的不可变商店,你甚至可以避免做像Flux和Redux这样复杂的事情 .
BaseView 类继承和处理商店更新
How to use
简单的 Store 类示例
Store instance 作为单身人士
我认为这消除了较小应用程序所需的所有苛刻框架 . 尽管与Immutable.js结合使用,还可以将redux用于中到大的 .
为了完成您所描述的内容,请尝试this.forceUpdate() .
如果希望两个React组件进行通信(不受关系(父子)约束),建议使用Flux或类似的体系结构 .
您要做的是监听可观察组件存储的更改,该组件存储保存模型及其接口,并保存导致渲染更改为
MyComponent
中的state
的数据 . 当商店推送新数据时,您可以更改组件的状态,从而自动触发渲染 .通常你应该尽量避免使用
forceUpdate()
. 从文档:应避免使用
forceUpdate
,因为它偏离了React的思维模式 . React文档引用了一个可能使用forceUpdate
的示例:但是,我想提出一个想法,即使使用深度嵌套的对象,
forceUpdate
也是不必要的 . 通过使用不可变数据源跟踪变化变得便宜;更改将始终生成一个新对象,因此我们只需要检查对象的引用是否已更改 . 您可以使用库Immutable JS在应用程序中实现不可变数据对象 .更改要重新渲染的元素的键将起作用 . 通过状态在元素上设置关键支柱,然后在您想要更新设置状态以获得新密钥时 .
然后发生更改并重置密钥
我想要注意,这将取代密钥正在改变的元素 . 这可能有用的一个示例是当您有一个文件输入字段,您希望在图像上载后重置 .
虽然OP的问题的真正答案是
forceUpdate()
我发现这个解决方案在不同情况下有用 . 我还要注意,如果您发现自己使用forceUpdate
,您可能需要查看代码并查看是否有其他方法可以执行操作 .我通过执行以下操作避免了forceUpdate
所以通过这样的代码改进,你的组件将是 UNIQUE 并自然渲染
forceUpdate();
方法可行,但建议使用setState();
你可以通过以下两种方式做到:
1. Use the forceUpdate() method:
使用
forceUpdate()
方法时可能会出现一些故障 . 一个例子是它忽略shouldComponentUpdate()
方法并且无论shouldComponentUpdate()
是否返回false都将重新呈现视图 . 因此,应尽可能避免使用forceUpdate() .2. Passing this.state to the setState() method
以下代码行克服了上一个示例的问题:
实际上,所有这一切都是用触发重新渲染的当前状态覆盖当前状态 . 这仍然不是最好的做事方式,但它确实克服了使用forceUpdate()方法可能遇到的一些故障 .
ES6 - 我提供了一个例子,对我有帮助:
在“短if语句”中,您可以传递空函数,如下所示:
这似乎是最短的方法 .
在您的组件中,您可以调用
this.forceUpdate()
强制重新呈现 .文件:https://facebook.github.io/react/docs/component-api.html
我们可以使用this.forceUpdate(),如下所示 .
即使您使用setState重新呈现组件,DOM中的Element'Math.random'部分也只会更新 .
一切这里的答案是正确的补充理解的问题..我们知道使用setState({})重新渲染组件是使用forceUpdate() .
上面的代码使用setState运行,如下所示 .
只是另一个回复备份接受的答案:-)
React不鼓励
forceUpdate()
的使用,因为它们通常对函数式编程采用非常方法 . 在许多情况下这很好,但是许多React开发人员都带有OO背景,并且使用这种方法,听取可观察对象是完全可以的 .如果你这样做,你可能知道你必须重新渲染observable "fires",因此,你应该使用
forceUpdate()
,它实际上是一个加号shouldComponentUpdate()
不参与此处 .像MobX这样采用OO方法的工具实际上是在表面下执行此操作(实际上MobX直接调用
render()
)实际上,
forceUpdate()
是唯一正确的解决方案,因为setState()
可能 not 如果在shouldComponentUpdate()
中实现了额外的逻辑或者它只是返回false
时触发重新渲染 .forceUpdate()
setState()
可以通过
this.forceUpdate()
从组件中调用forceUpdate()