React Native/Redux应用程序中的可能导航问题
在使用Redux在大React Native应用程序中导航期间,所有访问的场景(导航堆栈的场景)都将保持安装状态。所有这些场景都会接收道具,并在从最后一个场景组件分派任何动作时按照它们访问的顺序进行渲染。它会导致冻结和分派与上次场景呈现之间的可见延迟。React Native/Redux应用程序中的可能导航问题
对于导航,我正在使用react-native-router-flux,但原来的React Native Navigator也出现了同样的问题。
视频Possible navigation issues in React Native/Redux app
会很高兴地知道如何防止通过道具不是从导航链集中的组件。
此刻,我正在检查每个组件的shouldComponentUpdate,如果这个组件是聚焦(可见)并在相反的情况下返回false。
有没有更好的解决方案?
我还没有使用react-native-router-flux,但是我有一个相当大的React Native和Redux应用程序的经验。我注意到,有时如果你所使用的数据变得足够大,可能会引起明显的延迟,但这些数据大多局限于在开发中工作。当应用程序建立时,它通常明显更快。看起来好像Redux在开发和生产模式中有些不同。
关于仍在安装导航堆栈中的场景,这是有意设计的。即使您将navigator.push
更改为另一个屏幕,那些以前的屏幕仍会保持安装状态,直到它们从currentRouteStack
弹出或由currentRouteStack
替换。
另外,可能值得注意的是您的模拟器处于慢动画模式。不知道你是否为了视频而做了这件事,但导航迟缓的部分原因在于此。只是在没有故意的情况下提出来。
我会检查应用程序在创建完成后如何工作,并且在进一步排除性能问题之前,它不处于开发模式。可能不是最终应用产品的问题。
谢谢你这么快的回答。此问题也发生在生产模式下的真实设备上。这些延迟主要取决于导航堆栈的大型场景。在上面的示例中,在开始场景中显示了1000个元素的巨大列表,以强调这些延迟。在真正的应用程序中,我正在努力处理这些延迟并不那么大但很重要。 视频示例中场景之间的转换等于2s。不是慢模式。 所以我正在寻找更好的方法来防止渲染,甚至道具传递不可见的场景。目前我正在使用检查shouldComponentUpdate – alexsh
嗯,有趣。我看到你正在将这些元素渲染成ScrollView。我会很好奇看看ListView会对性能产生什么影响。我相信他们用来渲染ListView行还有额外的性能改进。可能值得研究。 – jasonmerino
我建议您使用场景和标题渲染方法中的导航索引来计算当前场景和场景之间的场景距离。如果距离> 1返回null。
这应该防止呈现整个导航历史记录。对我来说,这种行为不是开箱即用的,但它确实存在。
我打算在这里出现肢体,但是您是否使用以下方法之一来防止重新渲染?
- PureComponents(在加入阵营15.3我觉得)手动浅
- 比较shouldComponentUpdate方法道具和状态。
默认情况下,React将在更新时重新呈现所有组件,除非您正确处理shouldComponentUpdate。
我在做类似的事情,并在所有
的问题确实是整个导航堆栈连接到店里没有这些问题(因为除非你使用resetto或resetnavigation部件不卸载)
这里值得一提的是我现在要做的。 我一直在使用稍加修改的反应终极版的实现,跳过对于不考虑场景更新(见下文)
要使用它,你需要:
存储在上下文中一个组件树的路径
我们创建了一个包装为此
const CurrentRoute = React.createClass({
childContextTypes : { currentRoute: PropTypes.object },
getChildContext() {
return { currentRoute: this.props.route }
},
render() { return this.props.children; }
})
并用它在渲染场景
<CurrentRoute route={route}><CurrentScene navigate={navigate} route={route} index={index} /></CurrentRoute>
然后,您可以访问组件已被渲染到的路线。
存放在单 导航堆栈,我们在配置场景中使用此代码
let routeStack = [];
export const updateRouteStack = stack => routeStack = stack;
然后你可以使用这个稍微修改反应,Redux的连接功能,它会跳过更新,如果组件在另一个组件呈现树那么当前显示的一个 (或类似实现) https://github.com/reactjs/react-redux/compare/master...ganmor:master
可能可以打包这一点,但我还没有时间去考虑它。如果有人觉得这样做.. 希望可以帮助
我们通过简单地将所有屏幕包装在组件中来解决它。
我们有一个ScreenView组件包装了整个屏幕,并且我们传递了一个参数“restrictRerendersToRoutes”。
此屏幕连接到状态,我们更新我们状态下的currentScrene并将其暴露给此屏幕视图。
然后我们简单地限制重新渲染当屏幕背景与此shouldComponentUpdate实现:
shouldComponentUpdate(nextProps) {
if (!_.empty(this.props.restrictRerendersToRoutes)) {
return !!this.props.restrictRerendersToRoutes
.find((routeKey) => routeKey === nextProps.currentScene.name);
}
return true;
}
你能否提供一个更详细的例子,这将是非常有用的。谢谢! – David
HI!我与我的护士应用程序有同样的问题。你有没有找到解决方法? – David