-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Context api #4427
Support Context api #4427
Conversation
ComponentWrapper.wrap was a static method which handled both regular components and components wrapped with Redux provider. This change is needed to support React’s Context api. Context api shares similarities with redux, as components are also wrapped with a Provider. The only difference is that the component can be wrapped with multiple providers.
As Context api is available since React 16.6.x, I need to upgrade the playground app to RN 0.57.5 which supports it. Hopefully this won’t take too long.
Took me only 2 days to update…
Instead, the default callback is always invoked - what am I missing… gods of TypeScript heed my call
Hmm can you add more examples to PR description? For example how to use the new |
Wrapping registered components can be done by returning a functional component. For example: ``` Navigation.registerComponent('navigation.playground.ContextScreen', () => (props) => ( <TitleContext.Provider value={'Title from Provider'}> <ContextScreen {...props} /> </TitleContext.Provider> )); ```
And how the api is used if I just have plain component? |
@henrikra As usual, no change. |
So basically we could deprecate all those redux wrappers? Aka we would not have any redux dependencies in this project? |
Yes exactly. I already modified redux tests to this pattern, we can deprecate |
This is good! Tell me when you are done so I can review this also! :) |
@henrikra PR's actually ready - I'm just trying to figure out why our CI is giving me such hard time. For some reason Detox times out... |
@henrikra Absolutely - we'll review it tomorrow |
Good to hear! Hey since this PR is doing two things: can you specify files that has to be reviewed that are related to |
Looks good! On suggestions I think we could get the API from this Navigation.registerComponent('navigation.playground.ReduxScreen', () => (props) => (
<Provider store={reduxStore}>
<ReduxScreen {...props} />
</Provider>
)); to this Navigation.registerComponent('navigation.playground.ReduxScreen', (props) => (
<Provider store={reduxStore}>
<ReduxScreen {...props} />
</Provider>
)); Aka removing one arrow function. If you look |
@henrikra Thanks for reviewing! Also, I had to change the api 😕 Navigation.registerComponent('navigation.playground.ContextScreen', () => (props) => (
<TitleContext.Provider value={'Title from Provider'}>
<ContextScreen {...props} />
</TitleContext.Provider>
), ContextScreen); The motivation is that we need to hoist statics from the actual component to the wrapping component in order to support |
I think I have bit better idea. Could it be like this Navigation.registerComponent('navigation.playground.ContextScreen', (WrappedScreenComponent) => (
<TitleContext.Provider value={'Title from Provider'}>
<WrappedScreenComponent />
</TitleContext.Provider>
), MyComponentScreen); So basically Navigation.registerComponent('navigation.playground.ContextScreen', (WrappedScreenComponent) => <WrappedScreenComponent />, MyComponentScreen); |
Navigation.registerComponent('navigation.playground.ContextScreen', (WrappedScreenComponent) => <WrappedScreenComponent />, MyComponentScreen); This is a breaking change - we need to avoid breaking changes for now. The second argument needs needs to be a method which returns a Component, not an instance of a component. |
Okay what about same points as I said before but with extra function Navigation.registerComponent('navigation.playground.ContextScreen', () => (WrappedScreenComponent) => (
<TitleContext.Provider value={'Title from Provider'}>
<WrappedScreenComponent />
</TitleContext.Provider>
), MyComponentScreen); Navigation.registerComponent('navigation.playground.ContextScreen', () => (WrappedScreenComponent) => <WrappedScreenComponent />, MyComponentScreen); |
Or what about this kind of API: we provide HOC from library like // in component file
import {withNavigation} from 'react-native-navigation';
class MyCoolComponent extends React.Component {}
export default withNavigation(MyCoolComponent);
// in screen file
import MyCoolComponent from './MyCoolComponent';
Navigation.registerComponent('navigation.playground.ContextScreen', MyComponentScreen); What do you think about this? Yeah it is breaking but we can change function name so it is NOT breaking :D This feels most flexible to me. What do you think? |
…entProvider This prevents premature require of the Component which impacts performance
Hey @henrikra, I think we should merge the feature now as I don't have much time to work on it anymore. Lets keep discussing the api in a new issue - we can consider this api experimental in the next few versions until we're both satisfied with it. |
Sounds good |
The following PR introduces improved support for Context api and other api's which wrap the root view. ## Context api Navigation.registerComponent('navigation.playground.ContextScreen', () => (props) => ( <TitleContext.Provider value={'Title from Provider'}> <ContextScreen {...props} /> </TitleContext.Provider> ), () => ContextScreen); ## Redux Navigation.registerComponent('navigation.playground.ReduxScreen', () => (props) => ( <Provider store={reduxStore}> <ReduxScreen {...props} /> </Provider> ), () => ReduxScreen); ## Plain Component - not changed Navigation.registerComponent('navigation.playground.MyScreen', () => MyScreen); This PR also upgrades the TypeScript version to 3.2.0 and RN version used in the playground app to 0.57.7 * New Android build flavor - `reactNative57_7` * Unit test coverage is disabled, for some reason it broke after upgrading to RN 0.57.7
This PR adds improved support for React's Context api
As he playground app still used RN 51, I had to upgrade it first to RN 0.57.7 which turned out to be a bit of a challenge. I also took the opportunity to upgrade TypeScript to 3.2.
Context API
Obviously, using static context works as well without needing to wrap the component.
Redux
Plain Component
This pattern supports any library requiring the user to wrap the base component.