Reactjs React导航选项卡Navigator在父级状态更改时重新加载

Reactjs React导航选项卡Navigator在父级状态更改时重新加载,reactjs,react-native,Reactjs,React Native,我正在使用react navigation中的tabnavigator。我有一个看起来像这样的父组件 changeService(serviceName){ this.setState({ }); } render() { const { container } = styles return ( <View style={container}> <Header clientName = {this.state.project} serviceName =

我正在使用react navigation中的tabnavigator。我有一个看起来像这样的父组件

changeService(serviceName){
 this.setState({

 });
}

render() {
const { container } = styles
return (
<View style={container}>
  <Header
  clientName = {this.state.project}
  serviceName = {this.state.service}
  cancelClick = {this.handleExitClick}
  />
  <ServicesNavigator
  changeService = {this.changeService}
  />
</View>
);
}
export default (props) => {
 const { screenProps, ...otherProps } = props;
 const ServicesNavigator = makeServiceNavigator(props);
 return <ServicesNavigator screenProps={{ ...screenProps, ...otherProps 
 }} />
};

每当我尝试更改选项卡时,导航器将完全重新加载并返回默认选项卡选择。在不重置选项卡导航器的情况下,是否无法允许tabnavigors父状态变量更改

每当触发
tabBarOnPress
时,它都会请求更新父组件的状态。然后,由于组件生命周期的原因,状态更新将导致父组件及其所有子组件重新渲染。这就是为什么您的选项卡导航器总是被重置的原因

对于您的案例,有几种解决方案:

1-使用
shouldComponentUpdate
指导何时更新父组件。由于您希望在调用
changeService
时保留
ServicesNavigator
,因此您希望避免在相关状态项上重新呈现

shouldComponentUpdate(nextProps, nextState) {
    if (this.state.itemA !== nextState.itemA) {
        return false; // avoid re-rendering
    }
    return true;
}
这是肮脏的,但工作;但是,从长远来看,它会困扰您,因为它会导致父组件的行为不是幂等的

编辑:我忘了您有读取状态的
标题。如果在父组件中使用
shouldComponentUpdate
,则
Header
将不会收到新的道具。所以第一个选项是不正确的。很抱歉


2-不再让父组件保持状态。在示例代码中,父组件只有在其子组件需要相互通信和共享数据时才具有状态。那你为什么不把共享数据放在别的地方呢?最好的工具可以是状态管理库,如
mobx
redux
,它们可以很容易地与
react导航集成,我认为这是不可能的。您应该存储状态,然后根据它们进行渲染。感谢shouldParentUpdate的问题是,我需要更新父级,以便在状态更改时可以更新头,我只需要导航器不更新。添加mobx或redux的问题很简单,就是我有一个紧迫的最后期限,并且我试图避免学习新的东西,直到我把它弄出来:)。我想知道是否最好将navigator变成一个纯类组件,而不是理想的组件,因为我更喜欢使用功能组件,然后下周再看看redux。@AdamKatz更新了我的答案。很抱歉,第一种选择不能解决您的问题。您可能需要进一步研究,以反应的方式进行。
shouldComponentUpdate(nextProps, nextState) {
    if (this.state.itemA !== nextState.itemA) {
        return false; // avoid re-rendering
    }
    return true;
}