S
SolidJS3d ago
Paul

React vs Solid wrt contexts

Lets say I have a component.
const Foo = (.....
<component Provider>
<component />
</component Provider>
);

Foo.Bar = BarComponent.
const Foo = (.....
<component Provider>
<component />
</component Provider>
);

Foo.Bar = BarComponent.
In BarComponent I have
const ctx = useFooContext();
const ctx = useFooContext();
The problem here. Is that react follows a top to bottom strategy and will render out the components following the hierarchy. So FooProvider gets run first and the context is available.
Whereas with Solid, the BarComponent is then run first and then finds the context to be empty. Is there any way to work around this? I either want the BarComponent not be run:
Foo.Bar = BarComponent.
Foo.Bar = BarComponent.
Or to delay it until the context is available. Are there any solutions here? Thanks
10 Replies
Paul
PaulOP3d ago
I think I have a possible solution to side step this whole issue. Will try tomorrow.
Madaxen86
Madaxen862d ago
If you mean that ctx may be undefined. Make a
export const useFooContext = () => {
const ctx = useContext(FooContext);
if (!ctx) {
throw new Error("useFooContext must be used within a FooContextProvider");
}
return ctx;
};
export const useFooContext = () => {
const ctx = useContext(FooContext);
if (!ctx) {
throw new Error("useFooContext must be used within a FooContextProvider");
}
return ctx;
};
Now ctx is infered without undefined
Paul
PaulOP2d ago
Thanks for the reply. But that already exists.
Madaxen86
Madaxen862d ago
Are passing async data to the context or why is it undefined in the first render? It shouldn’t
Paul
PaulOP2d ago
No, no external data is being requested at all. You are missing the context 😄 https://github.com/paulm17/mantinesolid/blob/main/packages/%40mantine/core/src/component/Card/Card.tsx#L118 Due to this line.
Card.Section = CardSection;
Card.Section = CardSection;
When Card is loaded. CardSection immediately fires. And because it fires, this line is then executed: https://github.com/paulm17/mantinesolid/blob/main/packages/%40mantine/core/src/component/Card/CardSection/CardSection.tsx#L46
const ctx = useCardContext();
const ctx = useCardContext();
Before this line: https://github.com/paulm17/mantinesolid/blob/main/packages/%40mantine/core/src/component/Card/Card.tsx#L108
<CardProvider value={{ getStyles }}>
<CardProvider value={{ getStyles }}>
Hope that clarifies things. As I said above. React follows a different method of loading in components to Solid. That said. I'm about to refactor things a little by removing
Card.Section = CardSection;
Card.Section = CardSection;

from card.tsx and moving it to index.ts and hopefully this side steps the issue. I found this method late last night.
Madaxen86
Madaxen862d ago
I’d think resolving the children outside the context is probably the problem
const resolved = children(() => local.children);
const resolved = children(() => local.children);
I guess if you move that inside a context provider i should work
Paul
PaulOP2d ago
Unfortunately I don't think that's going to work. This pattern is used in many other components. I'm thankfully tacking a really simple use case. If I resolve this component, then I resolve all of them. I'm now using a store instead of a context and have managed to almost circumvent the issue. But reverting the code to show the issue completely:
No description
Paul
PaulOP2d ago
I put init right at the top of both components. So card starts to run but does not complete. The provider is not available when cardSection runs as well. 🤷‍♂️ * Could have sworn CardSection started before 😅 ...
Paul
PaulOP2d ago
Finally!
No description
Paul
PaulOP2d ago
No description

Did you find this page helpful?