yewstack / yew

Rust / Wasm framework for creating reliable and efficient web applications
https://yew.rs
Apache License 2.0
30.52k stars 1.42k forks source link

Question: Replacement for `Context` type #425

Closed prasannavl closed 4 years ago

prasannavl commented 5 years ago

Description

I'm submitting a: question

Just decided to give yew a shot, but came across the fact that the 0.4 version on crates.io has a Context type, that's passed along everywhere, and initialized with App:new(Ctx). It seems that it was just very recently removed in 0.5, and is no longer there.

I thought it was a very convenient way to access application context and services, however, now I'm wondering what the alternative exactly is. I see that there's something called ComponentLink, but only the create fn has access to it, while context was available throughout update, renderable, etc. And now, I'm also not exactly sure where to initialize the the context and pass it through to the application.

Since, there's not a lot of docs at this stage, I'm wondering if I can get some pointers, and the rationale for the Context removal, and replacement. Thanks!

Context (Environment)

hgzimmerman commented 5 years ago

I haven't used this project in a while, but if I recall correctly, there isn't a huge overhead to creating a service in each component, so there isn't a huge overhead to having something like 10 different StorageServices instantiated at a given time.

Alternatively, you can create bridges to Agents using ComponentLinks. You use the ComponentLink to create a callback with which you can call AgentImpl::bridge(callback) to get a Box<Bridge<AgentImpl>> that you store as part of your Component's Model. The callback will be called when the agent decides to broadcast a message, and you can send messages to the agent by using .send(AgentMsg::Variant) on that boxed bridge.

Agents are the effective replacement for Context, and the best way at the moment to understand them at the moment is to look at the source (maybe?) and examples. Using Context for the Agent's Reach will instantiate a single global instance of that agent, so the same agent can be accessed from other components.

The routing example makes use of agents. In your case, your agent wouldn't contain a RoutingService, but instead could just hold your global state.

I've written a proof of concept using Agents to allow components to communicate with arbitrary other components in a unidirectional fashion. It can be used as another example of how to implement an Agent, although this use case likely doesn't match what you are trying to accomplish.

jstarry commented 4 years ago

@prasannavl I hope @hgzimmerman's explanation helped! If not, please feel free to re-open :)