-
-
Notifications
You must be signed in to change notification settings - Fork 264
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
React Konva doesn't work with React 16.3 Context API #188
Comments
I published v Updated: currently it doesn't work directly, you have to use a workaround, see #188 (comment) |
This is still broken on v1.7.2. You can see in the reproducible demo linked above that it's picking up the default value defined by the initial creation of the context ( |
Tracking here: facebook/react#12796 |
Here's an example of a quick workaround I put together to try and sort of contain this. |
Any updates here? |
Usually when there are updates on an issue, they happen on the issue itself. :-) But since you're asking, facebook/react#13728 will likely help. It will be in the next React release. That would help you "bridge" the context you care about down. |
@Guria basically facebook/react#13728 is an API change which will make the necessity of re-introducing your context into the hierarchy at a point below the point at which the context barrier happens (the <MyConsumer>
{value =>
<Stage>
<MyContext.Provider value={value}>
<Stuff />
</MyContext.Provider>
</Stage>
}
</MyConsumer> you have: // or whatever your top level react-konva component where you care about context is
class MyStage extends React.Component {
static contextType = MyContext;
render() {
return <Stage>...</Stage>;
}
}
// ...
<MyStage>
<Stuff />
</MyStage> Because facebook/react#13728 doesn't implement any kind of introspection of context solution, I don't think that it offers a fix that react-konva could implement, and I think that facebook/react#13332 would be a potential direction for solving that problem. Does this sound about right @gaearon ? |
Yea |
Is the way to make it work with react-konva? My consumer returns default value of context |
Maybe allowing for something like this: function useForeignContext(context) {
const { subscribeContext } = useContext(ROOTCONTEXT)
const [wrappedContext, unsubscribe] = useMemo(
() => subscribeContext(context)
, [context])
useEffect(() => unsubscribe, [context])
return useContext(wrappedContext)
} Which would transport context into the reconciler tree. The root component that still belongs to the dom ( |
Demo how to "bridge" contexts into import React, { Component } from "react";
import Konva from "konva";
import { render } from "react-dom";
import { Stage, Layer, Rect } from "react-konva";
const ThemeContext = React.createContext("red");
const ThemedRect = () => {
const value = React.useContext(ThemeContext);
return (
<Rect x={20} y={50} width={100} height={100} fill={value} shadowBlur={10} />
);
};
const Canvas = () => {
return (
<ThemeContext.Consumer>
{value => (
<Stage width={window.innerWidth} height={window.innerHeight}>
<ThemeContext.Provider value={value}>
<Layer>
<ThemedRect />
</Layer>
</ThemeContext.Provider>
</Stage>
)}
</ThemeContext.Consumer>
);
};
class App extends Component {
render() {
return (
<ThemeContext.Provider value="blue">
<Canvas />
</ThemeContext.Provider>
);
}
}
render(<App />, document.getElementById("root")); |
I am going to close the issue. I don't think we can do anything from our side to resolve the issue and handle context bridging automatically. |
I encountered this issue with my project. After playing with it, I realize that we can skip the bridge by declaring the context consumer inside
https://codesandbox.io/s/react-konva-consume-context-demo-d5yht |
@harryhle That seems unrelated as you're not actually bridging the gap between the two renderers there, both the provider and the consumer are on the |
@lyleunderwood That's right. I actually work around this problem by passing data between two renderers with |
Is there a way to bridge react-query's |
import { useQueryClient, QueryClientProvider } from 'react-query';
const Canvas = () => {
const queryClient = useQueryClient();
return (
<Stage>
<QueryClientProvider client={queryClient}>
<Layer>
{/* ... */}
</Layer>
</QueryClientProvider>
</Stage>
);
}; |
Similarly for MUI we should be able to do something like: import { ThemeProvider, useTheme } from '@material-ui/core/styles';
const Canvas = () => {
const theme = useTheme();
return (
<Stage>
<ThemeProvider theme={theme}>
<Layer>
{/* ... */}
</Layer>
</ThemeProvider>
</Stage>
);
}; |
@lyleunderwood Thanks! I actually had implemented it in such a way for the |
… api [how] - implement CommentThread, CommentStarter - adopt moment.js to display timestamp - complete remove comment and update comment thread actions - extract canvas component - replace prop drilling with context [reference] According to the following discussion, react-konva <Stage> will influence the Context API: konvajs/react-konva#188 Redux is based on Context API, so it is influenced too konvajs/react-konva#311
The usage of context api should probably be an example on the offical docs site, there is no mention there of this problem/pitfall and I only found this due to some google searches (which first led me in other directions). |
Update on this issue. From |
I've just tested the new version and the context bridge its working fine on my case 👍 |
Thanks for the update that works now :) |
Can you make a demo? |
I am trying to use React 16.3 Context API based on render props with React Konva:
And I get runtime error:
Reproducible demo: https://codesandbox.io/s/2o9j1r6l30
The text was updated successfully, but these errors were encountered: