3

I have made a HOC for showing a loading modal when my component is loading.

export const withLoading = (Component) => {
    return function HOCLoading(props) {
        const [isLoading, setIsLoading] = useState(false)
        return (
            <>
                <Component
                    {...props}
                    isLoading={isLoading}
                    setIsLoading={setIsLoading}
                />
                <Loading isLoading={isLoading} />
            </>
        )
    }
}

And I'm using it as

export default withLoading(MyComponent)

It was working fine until I realize that the navigationOptions stopped working, which is obvious because withLoading return a component that don't have navigationOptions, so my workaround was.

const LoadingMyComponent = withLoading(MyComponent)

And then set navigationOptions to LoadingMyComponent.

But this looks bad and doesn't make it easier than having a state for loading and rendering Loading.

Is there a way to transform this HOC into a react hooks or do something that I don't mess with the navigationOptions and also encapsulates the Loading component and logic?

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Vencovsky
  • 28,550
  • 17
  • 109
  • 176

1 Answers1

0

I've had the exact same problem with react-navigation and I'm pretty sure that no really clean solutions exist, as the concept of setting a navigationOptions static property isn't, in the first place, really good (they should have made a hook for that in my opinion).

So either you copy navigationOptions (what you're doing), or, if this is not too problematic with your current architecture, you put everything in a MyScreen component that isn't wrapped by another HOC, like this:

const LoadingMyComponent = withLoading(MyComponent);

function MyScreen() {
  // You can exchange data with props or contexts if needed
  return <LoadingMyComponent />;
}

MyScreen.navigationOptions = { /* ... */ };

// MyScreen is never wrapped in a HOC and its navigationOptions are accessible
MrAnima
  • 555
  • 1
  • 4
  • 13