brianzinn / react-babylonjs

React for Babylon 3D engine
https://brianzinn.github.io/react-babylonjs/
822 stars 105 forks source link

Context lost in child components (Error with providers like Redux, React Router and Zustand) #236

Closed saidmoya12 closed 2 years ago

saidmoya12 commented 2 years ago

I would like to know if it is possible to keep the "context" in the child components of scene

Child components lose context within the scene, so I have problems with react router, redux or zustand hooks inside child components

I know it's a context issue, because I was able to fix react-routerV5 with the following code

<Scene>
    <RouterContext.Provider value={router}>
        <HistoryContext.Provider value={history}> {/*useParams (react-router) works so but only for V5 with this fix */}
            <MyChildComponent/> {/*useDispatch (redux), useStore (zustand) doesn't work :( */}
        </HistoryContext.Provider>
    </RouterContext.Provider>
</Scene>

Thanks.

brianzinn commented 2 years ago

Good question @saidmoya12 -- It's a known "bug" with React context crossing renderer boundaries. Are you able to make a bridge like this? https://github.com/brianzinn/react-babylonjs/blob/master/packages/storybook/stories/babylonjs/Basic/contextBridge.stories.js#L28

You should only need to do it once to bring it across into your <Scene>...</Scene>.

cjjkoko commented 2 years ago

maybe: function testHook(fn) { const { store } = useReduxContext(); const [state, set] = useState(null); useEfferct((fn) => { const fun = () => { return set(fn(store.getState())); }; const unsub = store.subscribe(fun); return unsub() }, [store]); return state; }

const ThemedBox = (props) => { const contextValue = testHook((state) => state.design); console.log(contextValue); return ; }

can work well

brianzinn commented 2 years ago

Thanks for adding to the conversation @cjjkoko, but it looks like it does not capture the context before the renderer switches!

Closing from inactivity - please re-open if you have more feedback. There is also a generic way to bridge the context in drei (https://github.com/pmndrs/drei#usecontextbridge).

drcmda commented 2 years ago

@brianzinn https://github.com/pmndrs/its-fine this solves the issue completely. we will be using this ootb for canvas from now on.

brianzinn commented 2 years ago

@drcmda - let me know when you bring that into r3f (it sounds like that is your intention) -- Very interested to look at how you will integrate it and would consider adding as a dep - lots of people get caught up on the renderer boundary. I've been switching all my demos to zustand as it solves the renderer boundary issues seamlessly.

Looks like I just useContextBridge and flow the {children} to the bridge. Highly cool.