miyabi / react-native-safe-area

React Native module to retrieve safe area insets for iOS 11 or later.
MIT License
113 stars 23 forks source link

Can't find variable SafeArea periodically #14

Open pribeh opened 5 years ago

pribeh commented 5 years ago

Thanks for this superb lib. I think I might have something setup wrong or perhaps there's a bug but I'm receiving a "can't find ... variable" error periodically when loading the app in development mode.

Below is how I'm integrating safearea in my components/screens. Let me know if there's something wrong with it.

import { SafeArea } from 'react-native-safe-area';

class SomethingScreen extends React.Component {

async getSafeAreaInsets() {
        const safeAreaInsets = await SafeArea.getSafeAreaInsetsForRootView()

        topSafeArea = Platform.OS === 'ios' ? safeAreaInsets.top : 0
        bottomSafeArea = Platform.OS === 'ios' ? safeAreaInsets.bottom + 13 : 0
    }
}
pribeh commented 5 years ago

I believe I had this incorrectly defined in a screen that was being called periodically.

pribeh commented 5 years ago

It's happening again with the above code. Additional notes, I'm running RN 0.57 and Mobx 5.9.0.

pribeh commented 5 years ago

Any help would be much appreciated. It appears as if some sort of race condition is impacting whether we can get a defined value. This is also impacting dynamic layouts such as when using libraries such as recyclerlistview that needs to know heights when rendering or re-rendering. In some of those instances we're getting varied values of undefined values consistently sometimes and others periodically.

miyabi commented 5 years ago

@pribeh I'm not sure about Mobx because I don't use it. If you want to apply safe area insets' changes to your view automatically, please try withSafeArea. Another option, you can handle safeAreaInsetsForRootViewDidChange event manually like this:

export class YourView extends React.Component<Props, State> {
  onSafeAreaInsetsDidChange = this.onSafeAreaInsetsDidChange.bind(this)

  componentWillMount(): void {
    SafeArea.getSafeAreaInsetsForRootView()
      .then(result => this.onSafeAreaInsetsDidChange(result))
  }

  componentDidMount(): void {
    SafeArea.addEventListener('safeAreaInsetsForRootViewDidChange', this.onSafeAreaInsetsDidChange)
  }

  componentWillUnmount(): void {
    SafeArea.removeEventListener('safeAreaInsetsForRootViewDidChange', this.onSafeAreaInsetsDidChange)
  }

  onSafeAreaInsetsDidChange(result: { safeAreaInsets: SafeAreaInsets }): void {
    // Update state here
  }
}