-
-
Notifications
You must be signed in to change notification settings - Fork 85
Class components ignore Providers in newer versions of React. #132
Comments
A Provider would be the solution to having two stores in one code base. You do not need a // empty default state module
state = { };
// TypeScript believes the state to be {}
// setup file
state.x = true;
// TypeScript believes the state to be {}, because TypeScript does not infer runtime code
// Provider/Store
const x = createProvider({ shape });
// TypeScript believes the state to be { shape }
// consumer
const state = x.getGlobal();
// TypeScript believes the state to be { shape } Hope this makes sense. Since a Provider is created by passing a typed state object, TypeScript infers that the Provider's shape is the same as that state object going forward. const Provider: ReactNProvider<T> = createProvider<T>(defaultState as T); The default global state needing a Providers are instantiated as the correct shape and therefore do not need their TypeScript definitions overridden. Whatever the type of the object that you pass to Let me know if yo need more assistance. |
Thanks @CharlesStover, switching over to the Provider model did it. I wonder if it's worth calling this out a little more explicitly? If this is the recommended model for having a web and native codebase, and there's a chance that someone is going to eventually have both, it seems worthwhile to start with the Provider model vs the hassle of switching later. |
@CharlesStover Actually, I got it working for my functional components, but I'm having two issues when trying to use the new Provider model with my class-based components:
|
For the former, how do you mean "returns {} initially"? As in it is {} but on the next rerender it is the correct global object? Or does There is no way to fix the latter. TypeScript can have no knowledge of which Provider is parent to the component. As an example:
In the above scenario, how would MyComponent know that You may have to use |
@CharlesStover For the latter, that's right. I had the same intuition about TS not being able to know the type of the global state in this case, but since it wasn't mentioned in the doc I just wanted to be sure. Typecasting works well. For the first issue, I think I'm setting things up right since hooks work great, but copied the code below: Store.tsx:
App.tsx:
AComponent.tsx:
|
Sorry for the late reply. You're right. It looks like for newer versions of React, class components are not correctly able to access the global state via the context when the global state is coming from a Provider. I'm not sure there is a backwards compatible way of handling this, since the new context API does not support old contexts, and the old context API does not support new contexts! It is difficult to write a class component that hooks into all possible React contexts. I'll document this for the time being as a known issue. Thank you for reporting it. |
I'm using Expo with a web project and a native project that are both part of the same package / project / repo.
Is there any suggested way to structure multiple reactn stores for Typescript - one for the web and one for native? Using 'global.d.ts' you can't have multiple store type definitions it seems like.
The obvious answer seems to be to use Providers instead, but just curious if anyone else has come across this use case. I don't see documentation in the Providers readme on how to structure the typescript type definitions
EDIT: I also tried conditionally declaring the module by using a conditional on react-native Platform, but that didn't seem to work either.
The text was updated successfully, but these errors were encountered: