我正在构建一个PhotoViewer,当用户按下left或right时,它会改变照片。我使用React、Redux、react-router和react-router-redux。当用户按下left或right时,我会做两件事,一是使用this.context.replace()
更新url,二是调度一个操作来更新当前查看的照片this.props.dispatch(setPhoto(photoId))
。我订阅状态更改以进行调试。
上面的每一行都会触发一个新的状态变化。由于我更新了currentlyViewedPhoto
,所以调度一个操作会更新存储;由于react-router-redux更新了存储中的url,所以更新url也会更新存储。当我调度操作时,在第一个重新呈现周期中,组件的render
函数被调用了两次。在第二个重新呈现周期中,组件的render
函数被调用一次。这正常吗?下面是相关代码:
class PhotoViewer extends Component {
pressLeftOrRightKey(e) {
... code to detect that left or right arrow was pressed ...
// Dispatching the action triggers a state update
// render is called once after the following line
this.props.dispatch(setPhoto(photoId)) // assume photoId is correct
// Changing the url triggers a state update
// render is called twice
this.context.router.replace(url) // assume url is correct
return
}
render() {
return (
<div>Test</div>
)
}
}
function select(state) {
return state
}
export default connect(select)(PhotoViewer)
render被调用三次是正常的吗?这看起来有点小题大做,因为React将不得不做三次DOM比较。我想这并不重要,因为什么都没有改变。我是这个工具集的新手,所以请随时提出关于这个问题的任何问题。
6条答案
按热度按时间zazmityj1#
如果在三个不同阶段设置状态,则组件也将重新呈现三次。
setState()将始终触发重新呈现,除非在shouldComponentUpdate()中实现了条件呈现逻辑。
(来源)
您可以在shouldComponentUpdate()中实作逻辑,以防止在遇到效能问题时发生不必要的重新转译。
ntjbwcob2#
我认为这是正常的。如果你没有明显的性能问题,我不会担心。如果性能开始成为一个问题,如果你确定某些状态改变不会改变呈现的组件,你可以考虑覆盖
shouldComponentUpdate
生命周期方法。编辑:如果你只需要在你的
shouldComponentUpdate
生命周期方法中进行肤浅的比较,你也可以考虑扩展React.PureComponent
而不是React.Component
。6ljaweal3#
这是一个老问题,我明白了,但我也注意到了这个问题。就像唐纳德的回答中所指出的那样,这似乎是正常的。我尝试了三种方法来解决我的具体情况:
前两种方法
禁用React DevTools插件不会更改记录到控制台中的消息数。
改变浏览器也没有效果,我试了Chromium和Firefox。
第三种方法
即使是最简单的组件似乎也会多次调用生命周期方法。
给定两个文件
App.js
和components/TestComponent.js
,如下所示:第一个
Test的生命周期方法被多次调用。
备注
结果和讨论
使用
yarn start
,我在控制台中得到以下内容:至少对我来说,
yarn
注意到开发版本没有优化,运行yarn build
,然后用python -m http.server --directory build
提供它,得到的页面没有重复的消息。至于为什么你得到三个渲染而不是两个,我不能说。我的建议是尝试构建应用程序,看看问题是否在生产构建中仍然存在。
如果仍然遇到这个问题,也可以按照Donald的建议在
shouldComponentUpdate
中实现逻辑。ecfdbz9o4#
如果使用〉v16.3,则尝试删除**<React.StrictMode>**,它应该工作正常。
为什么?自从v16.3用于类组件和v16.8用于钩子以来,React引入了 <React.StrictMode> 以便使到Concurrent React的过渡(在不久的将来)更加 * 对开发人员友好 *,因为渲染阶段可以被多次调用。
以下文章值得一读:
React Components rendered Twice
React Components render twice and drive me crazy
Wait, you're not using <React.StrictMode>?!
注意:这仅适用于开发环境。
1sbrub3j5#
我<React.StrictMode>的案子也是这样
n3ipq98p6#
您可以在以下操作之前删除
React.StrictMode
:至:之前:
index.js
中的文件默认值