Skip to content

Instantly share code, notes, and snippets.

@ritikrishu
Last active June 3, 2019 07:46
Show Gist options
  • Save ritikrishu/1a866e4f720408e057273df387762b44 to your computer and use it in GitHub Desktop.
Save ritikrishu/1a866e4f720408e057273df387762b44 to your computer and use it in GitHub Desktop.
React native offline screen wrapper example
export default function connectionAwareActivity(WrappedComponent) {
return class extends PureComponent {
constructor(props) {
super(props);
this.state = { isConnected: false };
this.switchConnectivity = this.switchConnectivity.bind(this);
}
static navigationOptions = WrappedComponent.navigationOptions
componentDidMount() {
NetInfo.addEventListener('connectionChange', this.switchConnectivity);
NetInfo.isConnected.fetch().then(isConnected => {
this.setState({ isConnected });
});
}
componentWillUnmount(){
NetInfo.removeEventListener('connectionChange', this.switchConnectivity);
}
switchConnectivity(type) {
if(type === 'none'){
this.setState({isConnected: false})
}
else{
this.setState({isConnected: true})
}
}
render() {
return this.state.isConnected ? (
<WrappedComponent {...this.props} />
) : (
<OfflineScreen/>
);
}
};
}
@ritikrishu
Copy link
Author

The goal is to wrap around offline screen component into any wrapped component passed. The header should stay as they are in WrappedComponent while the content should show offline design.
I am then using this like-

import{ connectionAwareActivity as cAA } from './sdk'
export default (Router = StackNavigator({
    Splash: {
        screen: cAA(SplashScreen)
    },
    Screen1: {
        screen: cAA(Screen1)
    },
    Screen2: {
        screen: cAA(Screen2)
    },
    ...
})

Problem with this approach is that render is being called twice in offline case, is there any way to know this before the first call to render so that state can be decided initially?
I can use async/await in render, but won't it block UI rendering?

@tejashwikalptaru
Copy link

tejashwikalptaru commented Jan 9, 2018

Have you tried replacing componentDidMount with componentWillMount ?
According to lifecycle docs, the componentDidMount runs after the first render, and hence after the first render in componentDidMount you are changing the state, which will result in second render call.
musefind
gitbooks
react component

You should also handle "unknown" case with "none" and by the way fetch() is deprecated:
React native docs

@ritikrishu
Copy link
Author

@tejashwikalptaru yes it is, should use getConnectionInfo instead, but both API's return promise or take callback, this is just example code to represent the problem.
I've already tried componentWillMount but placing console.log('render was called') in render function still logs twice on screen navigation.
render

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment