这里的问题比标题更深入,如果您可以更好地重新说出来,可以自由编辑。
在我的应用程序中,有很多不同的页面需要在显示和隐藏NavigationBar
组件之间切换。我正在使用Redux
来管理我的应用程序状态,并使用componentWillMount()
发送一个调度,说明该页面已加载,以通过作为propBrote实例的prop传递的变量启用或禁用状态栏
为了给你一个快速(和杂乱)的例子,请检查下面的代码:
const CustomNavigationBar = connect( (state) => {
return {
navigationBarHidden: state.navigationReducer.navigationBarHidden
}
})(React.createClass({
render() {
if (this.props.navigationBarHidden) {
return null;
}
return <Navigator.NavigationBar {...this.props} />
}
}))
除了一些我希望使用pop()
的情况外,此方法正在运行。虽然pop()
将卸载当前路由,但前一个路由仍然挂载在内存中,因此当使用pop()
返回页面时,永远不会调用componentWillMount()
函数。
我心想,好吧所以我只会使用resetTo(...)
然而事实证明,当它再次激发componentWillMount()
时,页面之间没有过渡。
这让我replacePreviousAndPop(...)
做了我想做的事情。它替换并重置之前再次调用componentWillMount()
的路由,但它表明在此过程中多次调用connect()
函数而不是一次,这意味着组件在导航期间被多次加载
所以,这让我感到push(...)
过渡,就像你前进而不是倒退,但让我担心记忆,因为之前的路线从未卸下过。这是否意味着每个路由都会有多个实例,并且每次用户导航时内存使用量都会增加?
也许我在这里缺少一些非常重要的东西,但总体目标是调用一个在页面进入视图时改变状态的函数。不是每次重新渲染。 componentWillMount()
做得很好,直到涉及导航。
显然我可以在这里使用一些黑客,但我无法相信导航器本身无法做到这一点。
**编辑:** @DavinTryon建议检出componentWillUpdate()
但是当你pop()
来自teh堆栈的当前路由时也不会调用它,即使你调用的组件componentWillUpdate()
是由于pop()
EDIT2: David先前的评论让我考虑componentWillReceiveProps()
方法,考虑redux-react
通过connect()
功能向组件添加道具。事实证明,当pop()
当前路线
“黑客攻击”的想法包括一个类级变量,该变量表明是否应该发送onLoaded调度。 (var dispatchRequired
)将在render()
函数中检查此变量,并在必要时调用dispatch()
。在发送dispatchRequired
之前,dispatch()
将设置为false,就像保护无限循环的故障保护一样,当导航离开时,dispatchRequired将被设置为true,这样在下一次渲染时它将再次调用该方法。例如:
class Example extends Component {
constructor(props) {
super(props)
this.dispatchRequired = true
}
navigateAway() {
this.dispatchRequired = true
this.props.navigator.push({
id: 'next-controller'
})
}
render() {
if(this.dispatchRequired) {
this.dispatchRequired = false
this.props.sendDispatch()
}
return <TouchableHighlight onPressed={this.navigateAway.bind(this)}> ... </TouchableHighlight>
}
}
export default connect( (connect) => {
return {}
}, (dispatch) => {
return {
sendDispatch: () => dispatch({'PAGE_LOADED', payload: {hideNavigation: true}})
}
})(Example)
EDIT3:这个黑客不起作用。事实证明render()
函数在pop()
返回到前一个路由时从未被调用过,我认为这是因为react没有检测到任何状态变化,因此render()
方法永远不需要被称为。
EDIT4:新的黑客
所以这是我提出的一个新的黑客,它可以工作,但它很烦人。基本上在mapDispatchToProps
函数的connect()
回调中,您会在超时后手动发送调度。非常hacky,但有效。
export default connect( (state) => {
return {}
}, (dispatch) => {
return {
gotoNext: (navigator) => {
navigator.push({
id: 'next-component'
})
setTimeout(()=>dispatch({type: PAGE_LOADED, payload: {hideNavigation: true}), 400)
}
}
})(Example)