【问题标题】:ReactNative componentDidMount doesn't get calledReact Native componentDidMount 没有被调用
【发布时间】:2019-03-29 09:01:16
【问题描述】:

我有两个屏幕:A 和 B,通过 StackNavigator 连接

屏幕 A 是二维码扫描仪。扫描二维码后,它会立即导航到屏幕 B。

在屏幕 B 中,我使用从屏幕 A 作为导航参数传递的 QR 码进行 API 调用。我在 componentDidMount 中触发此 API 调用。

我的问题是:如果我从 A 导航到 B,然后返回 A,然后再导航到 B,则不会调用 componentDidMount,并且我无法触发 API 调用。


编辑:

这里有一些代码

屏幕A

扫描二维码时调用的处理函数:

handleQRCode = qrCode => {
    NavigationService.navigate('Decode', {qrCode});
};

屏幕 B

二维码是从导航状态参数中提取出来的,用于通过 redux 进行 API 调用(startDecode)。

componentDidMount() {
    qrCode = this.props.navigation.state.params.qrCode;
    this.props.startDecode(qrCode.data);
}

我的问题是 componentDidMount 仅在第一次采用该路由时才被调用。

【问题讨论】:

  • 可以分享一段代码吗?
  • @JoseVf 我刚刚添加了一些代码

标签: react-native react-navigation


【解决方案1】:

我遇到了类似的问题,我使用this.props.navigation.addListener() 解决了它。基本上,可以通过再次推送同一屏幕using a key 来强制调用componentDidMount()(我还没有尝试过),但是您的堆栈也会不断增长,这不是最佳的。因此,当您返回到已经在堆栈中的屏幕时,您可以使用 addListener() 来查看它是否正在重新聚焦,您可以在此处复制您的 componentDidMount() 代码:

class MyClass extends Component {

  someProcess = () => {
    // Code common between componentDidMount() and willFocus()
  }

  componentDidMount() {
    this.someProcess();
  }

  willFocus = this.props.navigation.addListener(
    'willFocus',
    (payload) => {
      this.someProcess();
    }
  );

}

第一次调用MyClass 时,将调用componentDidMount。对于其他时间,当它仍在堆栈中但只是获得焦点时,addListener 将被调用。

【讨论】:

    【解决方案2】:

    react-navigation 中,每个屏幕都保持挂载状态。这意味着当您返回 B 时,您可能已经更改了 props,但在第一次创建此屏幕时已经调用了 componentDidMount

    有两个选项可供您(AFAIK)处理这种情况:

    1. 您可以使用而不是调用this.props.navigation.navigate() this.props.navigation.push 将创建另一个实例 屏幕 B,从而调用 componentDidMount React 生命周期 事件。
    2. 在屏幕 B 中,您可以捕捉到其道具发生变化的事件。 这可以发生在新的静态生命周期事件中 getDerivedPropsFromState 或者可以在不久的将来完成 已弃用 componentWillReceiveProps

    【讨论】:

    • 我尝试过像这样推送 -> this.props.navigation.push('Decode', {qrCode}) 但仍然没有调用 componentDidMount。
    • 我去B屏的时候也不一定会改变props,但是我希望它会再次触发API调用来刷新本地副本
    • 关于你的第一个回复 - 这真的很奇怪,因为根据定义 push 应该创建一个新实例,因此调用 componentDidMount
    • 关于您的第二次回复 - 如果您不更改道具而不是仅显示已安装的屏幕 B,则不会再次调用 componentDidMount
    【解决方案3】:

    这是因为 B 组件仅在第一次访问时才挂载,因此不会再次调用 componentDidMount。

    我建议您使用“didAppear”事件将回调传递给导航器的setOnNavigatorEvent 方法。您的回调将在 react-native-navigation 发出的每个事件上被调用,并且您可以在每次屏幕出现时验证是否执行您的逻辑(因此使用“didAppear”事件)。您可以根据以下内容编写代码:

    export default class ExampleScreen extends Component {
      constructor(props) {
        super(props);
        this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this));
      }
    
      onNavigatorEvent(event) {
        if (event.id === 'didAppear') {
          // do API call here
        }
      }
    }
    

    【讨论】:

    猜你喜欢
    • 2023-03-29
    • 2018-09-22
    • 2020-04-05
    • 2018-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多