-
Notifications
You must be signed in to change notification settings - Fork 47.4k
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
16.6 Context API not working in class component #13969
Comments
@javascrewpt While I do believe that is one way to use the Context API, have you looked at this: https://reactjs.org/docs/context.html#classcontexttype ?
By the looks of that, I should be able to do what I am attempting to do. |
@javascrewpt That is a solution, but the approach seems to avoid the original issue. Also, the top-level component could be used to store state and also provide methods that manipulate that state. In your last example, you would need to jump through more hoops to account for that. From what I can tell, this is the whole purpose of the changes to the context API in 16.6:
Quoted from: https://reactjs.org/blog/2018/10/23/react-v-16-6.html?no-cache=1#static-contexttype I appreciate your help. I would like to address the root of the issue or gain clarification of the intentions of the API. If the API is not supposed to work like I am attempting to use it, then I would propose (and even help) in clarifying the documentation so that others do not run into the same issue. |
@javascrewpt My issue is why do I have to create context in a separate file? Where in the docs does it say this? The example used in the docs has the context created in the same file: https://reactjs.org/docs/context.html#when-to-use-context When the docs say one thing and the code behaves differently, this is usually one of three things:
I am willing to accept any of the above. While you have provided a workaround, of sorts, it does not address the root cause. Now, on to your proposed solution. As I have previously stated/questioned, what if my top-level component tracks state and also passes methods to change that state (please see the original codesandbox, which I've update: https://codesandbox.io/s/r4myz959ro)? Your simple solution is no longer valid. I would have to completely refactor my solution to separate out the context provider into another top-level component that tracks state, etc. This may be the correct way to do it. But, then again, where is this documented? And, we are back to the original question and the root of the problem. The documentation makes it seem like my approach should work. It does not mention (anywhere that I can see) why it would not work. Is this a bug, a mistake in documentation, or did I interpret something incorrectly? I am not trying to dismiss your help and I appreciate you attempting to find a solution for the problem. However, if you are just trying to prove a point by telling me that you, "don't believe I am using it correctly" or that, "there is no bug and it works as intended", please do not feel that you need to help anymore. |
I'm sorry if I came off too aggressive, I wasn't trying to dismiss your issue, it's just my lack of knowledge about this that made me question the problem. And you elaborated perfectly and I understand now your concern. I'm looking forward to hearing from some experts about this, seems an interesting issue. |
@dericgw the problem you're describing has nothing to do with React, it's the behavior of circular ES6 module imports. Here's an example showing the same problem without React. The index file imports The reason it works with the |
Did u manage to resolve it? I'm facing similar issue. context is an empty object const Context = React.createContext();
class Child extends React.Component {
render() {
const renderedContext = this.context;
console.log({ this: this });
console.log(renderedContext);
console.log({ asd: Child.contextType });
return <div />;
}
}
Child.contextType = Context;
export const Test = props => (
<Context.Provider value={{ hello: 'world' }}>
<Child />
</Context.Provider>
); I'm quite sure I have no cyclic rendering, make sure I'm on |
Is it possible that it only work on production build? or I have try many many variation upgrade to I could not get it to work at all though… |
Can't get this to work either, enclosing in <.Consumer> works fine, but the static contextType object is always empty. |
For my case, I forgot to upgrade @clintjansen I think you might need react-native to official support 16.6.0 |
|
@jacksongabbard it seems like the codesandbox you shared is still using the 16.5.2 versions of React and React-dom and not 16.6.0, here is a codesandbox using 16.6 showing the context being assigned and rendered correctly: https://codesandbox.io/s/m31mv7wox9 |
Ah, indeed, indeed. I should've checked the changelog. I would've noted that the |
I ran into the same issue as @dericgw, and came to the same conclusion as #13969 (comment) by @aweary, that it is a circular dependency problem. I had to move the Context creation out into a separate file, that both the parent component (that holds the I don't know how common this problem is, but I agree with @dericgw that if you follow the documentation to the point, you run into this problem, which means there should probably be a note about it in the docs. |
I too was bitten by this and once I hoisted the context creation into its own file (i.e., one But I think the real issue here is the documentation (as noted above). Currently, it reads almost as a stream of consciousness, meandering between what not to do and ending up with potential pitfalls. There is a lack of prescriptive information that outlines clear use-cases and patterns to the developer. Agreed, this is a new API and patterns are still emerging so I'm afraid we'll be dealing with a depth-first tree-traversal of incorrect application models until stumbling on the right track as outlined in this thread (and I am very appreciative for the smart comments posted here that made my stuff work). |
File an issue about the docs in the docs repo please? It’s not really being tracked here. Thanks. |
cc @sebmarkbage on documentation rewrite feedback |
IMO we should warn if it looks like a circular dependency (empty object or |
I think the warning would be a good idea. This is a weird scenario that is hard to debug if the developer don't know the internal structures of dependencies, imports, etc., and I think that the offending pattern is a somewhat common mistake (I could be wrong on that though). But it would probably be a long warning explaining circular dependencies, if we don't add it to the docs and just point the developer there, so I've opened an issue in the docs repo - reactjs/react.dev#1481. Are there any cases where the developer actually wants the context to be |
I had same problem, but I used react 16.6.0 and react-dom 16.5.0 :) |
I had the same problem, but resolved after upgrading to react 16.6.0+. |
This is not currently working in Expo (version v32.0.0). See https://snack.expo.io/@badbod99/calm-candies. Code based on React Context example, updated for React Native. Setting contextType as 'ThemedButton.contextType = ThemeContext;' does not result in this.context having current context value from ThemeContext.Provider above. Using '<ThemeContext.Consumer>' does work. Not a circular reference issue nor a documentation problem. Context creation is in separate file. |
EDIT: Fixed, no more errors, thanks to next comment I tried to use static property Based on @javascrewpt example : https://codesandbox.io/s/8k9z6ww150
The result is the same when defining Using react / reactDOM 16.8.3 |
@elias551 Have you tried the fix suggested here #13969 (comment)? I had the same issue and moving the context creation into its own file fixed it for me. So my file structure was like:
|
@conor-kelleher thanks for the quick answer ! Sorry I was confused about the explaination I did not understand it correctly. Still, I have a similar problem in my project, and the Context is correctly defined in a separate module. I suppose I'm having a similar issue, there are index files at each folder auto exporting symbols, so I should check that. |
I had the exact same problem, running react native & using react-navigation.
As an observation having independent files or not changed nothing in all my tests. What fixed it for me, using react-navigation was to have my ContextProvider as the highest level of the application:
|
@sfourdrinier it solved my problem, thanks. I'm currently working on this project that auto imports every class and functions with index.js at root of any folder exporting every symbol recursively through directories. It is very confusing and error prone for me... You have to always be careful to import things in the right order and I did not find any tooling warning you consistently on potential cyclic dependencies. If your context is null using |
Oh dear. Any ideas why it was set up this way? This sounds like a recipe for trouble. |
@badbod99 Please report it to Expo. |
Already reported (and they replied). They've not yet updated expo to 16.8, so it doesn't yet support static contextType. Seems they have been waiting for RN 0.59 before making the next jump. No date as of yet. |
Ahh that makes sense. Thanks for explaining! |
I think the reason is purely aesthetic, the project favors imports with short paths, this way you have
instead of
If A depends of function B, then you have to remember to import with a relative path or else you have a cyclic dependency. Furthermore, the linter enforces to sort imports by alphebetical order... which can sometimes break imports with very few informations about which import is causing the error. |
In this issue, we've seen two kinds of problems:
We added a better warning for the circular dependency case in #15142 which will be included in next release. That should make the first case much easier to diagnose. For doc problems, I filed reactjs/react.dev#1842 to track them. The second problem will also gradually go away as more people update React. I don't think there's anything else actionable in this issue so I'm closing. Thanks everyone for feedback. |
The better warning is included with 16.8.6. |
moving
|
Exporting/importing removes circular dependency. This answer explains it perfectly https://stackoverflow.com/questions/56384761/cannot-access-class-contexttype-within-a-child-component |
Hi! React Context works perfectly on my application on development environment with Webpacker but when I precompile my assets to serve my application in production environment it throw me Here are the links for the code: Context Creation Context Provider Context Consumer |
Do you want to request a feature or report a bug?
Quite possibly a bug (or maybe confusion about the current API)
I am using the new Context API as well as the new
static contextType
in React 16.6. I am passing context down a couple components deep but when I attempt to access the context within the component, the object is empty (only the default value passed into). This is happening in a current feature I am working on at my job, so I cannot display that code, but I did create a Codesandbox with the gist of the problem.createContext
is being displayedHere is a demonstration of the behavior: https://codesandbox.io/s/r4myz959ro
I would expect to be able to access the current values of the context. This way, if those values change, I would always have the most recent values. Now, maybe this is expected behavior, however, it would be confusing if it is.
React 16.6
ReactDOM 16.6
The text was updated successfully, but these errors were encountered: