-
Notifications
You must be signed in to change notification settings - Fork 5
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
New crystal with contexts. #690
Conversation
AppCtx.runWithCtx { implicit appCtx => | ||
val ConstraintSetObsLiveQuery = | ||
ScalaFnComponent[View[ConstraintSetsWithObs] => VdomNode](render => | ||
AppCtx.using { implicit appCtx => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it so that we execute this on IO
when calling using
? Or is it different than runWitCtx
in that sense
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The inner workings are different than before. Ctx.using
(or Ctx.usingView
) return a VdomElement
, so they can only be used within render
. In other words, they act as a component; and since it's declarative, a name with run
in it didn't seem fitting anymore. Also, the function passed to them must be a render function, returning a VdomNode
.
This is a functionality provided by React, and is basically a way of "teleporting" props further down the component tree, without the need of explicitly passing them in all intermediate components. If the context changes, it is automatically propagated to all .using(View)
blocks in the currently rendered component tree.
"Explore" | ||
"Explore", | ||
HelpCtx.usingView { help => | ||
val helpMsg = help.zoom(HelpContext.msg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, this will be useful
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot, this was a lot of work but will be useful in a few important scenarios
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Crystal now uses React's context for storing, well, context. It provides a component to store context (
ContextProvider
) and a mechanism where consumers can use just the value of a context, or get aView
which allows modifying said context. Also, it supports multiple contexts.This PR includes a little demo on how to use it which is not meant to go into production. After we have implemented a proper help system, we can remove this:
One disadvantage of this approach is that we can't access contexts from lifecycle methods. Although React provides a way to do this, support in
scalajs-react
is pending (japgolly/scalajs-react#890). To work around this temporarily, context is passed implicitly in props from parents to child components who need it in lifecycle methods.The old
AppRoot
has been renamed toStateProvider
.