由于没有组件将导致React-Native Tab Navigator内存泄漏

时间:2019-04-05 14:20:30

标签: react-native navigation

我真的很困惑如何解决在移至新选项卡时取消异步过程的问题。如果您在页面上启动了一个异步请求,但是在完成之前导航到一个新选项卡,则会收到警告:“无法在已卸载的组件上调用setState(或forceUpdate)”

但是,通过选项卡导航器更改屏幕将永远不会触发willunmount,因此,没有真正的地方可以取消任何操作。 Stack Navigator和switch Navigator触发了此操作,我可以取消任何操作。我实际上将要建立自己的底层导航来解决此问题。

此示例是破解恕我直言的方法:

是的,我尝试了this.isMounted方法(顺便说一句,如果您使用isMounted(...),则现在不建议使用isMounted(...)警告)是的,我已经使用了willupdate方法,但是PureComponent应该用于删除该“ hack”。

对我来说,这确实感觉像是个错误,我迷失于如何进行底部导航并获得具有某些获取结果的页面。

//异步方法中的Hacky示例

Microsoft SQL Azure (RTM) - 12.0.2000.8 
    Mar 19 2019 04:06:22 
    Copyright (C) 2019 Microsoft Corporation


----------------------------------------------
<tag>aa</tag>

(1 row affected)

2 个答案:

答案 0 :(得分:0)

如果您使用的是Redux:

您可以将所有异步代码移至 Action ...

如果您是在某个操作中执行异步代码,而不是在组件生命周期内执行它,那么...如果用户决定移至其他选项卡并且未执行 action ,可以已解决((因为它在与组件生命周期不同的上下文中运行))...完成操作并且您的组件仍处于活动状态>>然后它将收到一组新的道具来更新自身... < / p>

关于在未安装的组件上设置状态……您可以将此模板用于任何具有状态的基于类的组件:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      // other fields...
      isUnmounted: false,
    };
  }

  componentWillUnmount() {
    this.setState({ isUnmounted: true });
  }

  setComponentState = (values) => {
    if (!this.state.isUnmounted) this.setState(values);
  };
}

答案 1 :(得分:0)

Redux并没有错,但是,对于我而言,它比所需的更为复杂。

因此,如果有人在React-Navigation Tab Navigator和异步获取方面苦苦挣扎。我能够实现我所追求的模式(触发事件以能够取消异步事件)。

当屏幕在(模糊)之间导航时,您可以添加侦听器

反应导航向订阅它们的屏幕组件发出事件:

willFocus - the screen will focus
didFocus - the screen focused (if there was a transition, the transition completed)
willBlur - the screen will be unfocused
didBlur - the screen unfocused (if there was a transition, the transition completed)

基本上我是这样做的:

async componentDidMount() {
console.log(SCREEN_NAME + ' Component Did Mount');

this.props.navigation.addListener('willBlur', (route) => {
  _isMounted = false;
  this.axiosCancelSource.cancel('Component unmounted.');
});

// didFocus will fire on 1st Mount as well
this.props.navigation.addListener('didFocus', async (route) => {
  _isMounted = true;
  this.axiosCancelSource = axios.CancelToken.source();     
  await this._getTourList();     
});
 console.log(SCREEN_NAME + ' Component Did Mount Complete');
 }

React-Navtive Navigation props web site