Skip to content
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

Add components #1

Closed
therustmonk opened this issue Dec 17, 2017 · 8 comments
Closed

Add components #1

therustmonk opened this issue Dec 17, 2017 · 8 comments

Comments

@therustmonk
Copy link
Member

Consider to add Component trait to add JSX-style reusable components:

<UserAvatar src={avatar} />
@wldcordeiro
Copy link
Contributor

@deniskolodin would this be a 0.2.0 feature too? I'd love to help with this one as it's the one abstraction I think would be nicest. 😄

@rivertam
Copy link
Contributor

rivertam commented Jan 2, 2018

I've been playing around with this implementation. I don't think I should be the implementer, based on the amount of trouble I've been having even coming up with an API, but I have some thoughts.

I think each component should have its own lifecycle almost identical to a full yew program. That is to say, each component should have a view, an update, and a model with an internal message type. Each component should also have a public Props struct (could be empty but actually must be named Props), and yew could implement a custom derive for the Props object using procedural macros, thus abstracting away the need for the component's user to ever actually use the Props "export" (JS terms because JS developer).

I ran into issues when trying to create a VComponent, and I also tried to make VTag compatible with components. Neither methodology "worked" for me and my Rust skills.

I implemented a potential example in this commit, so this was the example I was trying to get to compile and run.

Would love to hear thoughts on this.

I think we should really consider what the "modularity", "reusability", and "scaling" stories are for yew before coming up with the exact API for components. That said, I've been very happy with how React handles components, and I think a similar story might work very well for yew if we can work it in with Rust's type system. Callbacks and closures might also not work quite as well as they do in JS for passing up data to parent components, so we might want to have some sort of hook to pass a message up to the parent or global message handler. This is really where I started running into design issues.


I also read up on Elm's scaling story and was unimpressed due to the fact that (I believe) it relies on one global message type and model. I think we need a more rigid, opinionated component structure.

@wldcordeiro
Copy link
Contributor

@rivertam @deniskolodin I guess it's a matter of what feels best and where we're taking influence from? I agree that components should have their own lifecycles but I was thinking something more alike to React. I'm also not the strongest in Rust though. Maybe if we could enumerate the things we would want abstracted away we could figure out what that looks like in Rust.

@rivertam
Copy link
Contributor

rivertam commented Jan 2, 2018

The good thing about modeling after React is that it encourages "strict" typing very strongly with PropTypes. I wouldn't be mad at a 1-to-1 translation, if possible. The hardest part is probably going to be the macro if we go that route. For that reason, it might be better to avoid the JSX-style and stick with a direct component interpolation. Just a thought.

@wldcordeiro
Copy link
Contributor

@rivertam Agreed. It doesn't need to look too much like React. I was most interested in taking the ideas around its state management. The abstraction around setState, Props, State, etc is really well built and lets users encapsulate stuff well.

@rivertam
Copy link
Contributor

rivertam commented Jan 2, 2018

@wldcordeiro

I disagree about state management for two reasons.

  1. The way state management works in React is different than how yew does it. In React, state management is done through transformations. It is highly encouraged to not change the state directly, but rather return a new state based on the old state. This doesn't work so well in Rust, as it would require state-model subsets. E.g. If your state-model looks like { counter: u64, name: String }, and you just want to change counter, you'll have to create an entirely new state-model instance, where in React you just have to return { counter: counter + 1 }. This is also noted in the highest level update function, which treats the state as mutable rather than returning a new state.
  2. The way setState works is/would be quite inefficient. If we're not making massive ergonomic improvements by implementing it as React does, I don't think it's worth the tradeoff.

Another approach I've been thinking of is more Redux/Elm-like, which would be that we'd have "reducers" (update), "models", and "actions" (messages) which would be specified in the same file as the view and would only affect a certain part of the global model and only receive those messages. I have no idea how we'd implement it, but I feel this might be another reasonable approach.

@dalen
Copy link

dalen commented Jan 11, 2018

Basically copying the API in reason-react should work well. There each component has a message type and reducer to update the state: https://reasonml.github.io/reason-react/docs/en/state-actions-reducer.html

ReasonML is in many ways more similar to rust than Elm or JS anyway :)

@therustmonk
Copy link
Member Author

Components was implemented with #91 🎉

bors bot pushed a commit that referenced this issue Jun 3, 2019
bors bot pushed a commit that referenced this issue Sep 26, 2019
* Fix typo

* Require fmt in travis script

* Apply cargo format to all modules
jstarry pushed a commit that referenced this issue Sep 26, 2019
* Early msgs queue for Public worker

* Early msgs queue for Public worker

* update (#1)

* Fix typo

* Require fmt in travis script

* Apply cargo format to all modules

* ??

* Merge (#2)

* Fix typo

* Require fmt in travis script

* Apply cargo format to all modules

* avoid allocating in diff_classes

* avoid allocating for diff_kind

* avoid allocating for diff_value

* simplify diff_attributes and avoid allocations

* return iterator for diff_classes and diff_attributes

* rustfmt on vtags

* clean apply_diff

* more cleaning

* apply suggestions

* Update proc-macro2, syn and quote to 1.0

CLOSES #590

* Fixed typo

* Add support for optional callbacks to component properties

* Add tests for a component with optional callback

* Fix typo

* Add `Classes` to prelude

* binary ser/de issue fix

* merge (#3)

* Fix typo

* Require fmt in travis script

* Apply cargo format to all modules

* avoid allocating in diff_classes

* avoid allocating for diff_kind

* avoid allocating for diff_value

* simplify diff_attributes and avoid allocations

* return iterator for diff_classes and diff_attributes

* rustfmt on vtags

* clean apply_diff

* more cleaning

* apply suggestions

* Update proc-macro2, syn and quote to 1.0

CLOSES #590

* Fixed typo

* Add support for optional callbacks to component properties

* Add tests for a component with optional callback

* Fix typo

* Add `Classes` to prelude

* added bincode type for data ser de

* fixed Into func

* Update (#5)

* in yewstack org

* Initial implementation using an iterator adaptor to provide a coherent struct to implement Into<VNode> (via From<>) for

* update large table example to demonstrate new .html() method instead of 'for'

* ran cargo fmt

* Add a section for project templates to the README

* Change org to YewStack

* Implement FromIterator instead of wrapping iterator

* remove dead code

* ran fmt

* Add extend method to Classes

* change to union

* renamed union back to extend

* removed unused import of RangeFull

* update

* Fix touch events (#656)

* Update changelog for v0.9 release (#657)

* Implement Debug for ChildRenderer<T> (#655)

* Implement Debug for ChildRenderer<T>

* fix formatter type lifetime

* remove fmt

* cargo fmt

* Emit initial route to router subscribers (#634)

* Fix typo in RenderService (#658)

* Add From<&String> for Classes implementation

* @jstarry feedback

- cargo fmt
- rename DEDICATED_WORKERS_* to REMOTE_AGENTS_*
- remove unrelated changes

* TypeId ask key instead &str

* Remove .gitignore changes

* Update agent.rs

* Update agent.rs

* Fix merge conflict
jstarry pushed a commit that referenced this issue Jun 26, 2020
* Update run instructions

`python3 -m http.server --directory` flag was added in Python 3.7.
Change instructions to cd into static and skip the flag instead -
makes it work with earlier Pythons too.

* Add visual feedback for button click

The minimal example has a button, but clicking it does nothing. This
makes it hard to tell whether the example works or not.

This adds a label that is update when the button is clicked.

* Small improvements to crm example

* Add a heading to each scene to make it more obvious what the page is
for.

* Improve layout of input form by stack the inputs vertically.

* Add a little space between entries when displaying the list.

* Add a hint to the Description input that Markdown can be used.

* Add an explanation to the file_upload example

* Clarify purpose of var in fragments example

* Improve futures_wp example

* Add a second button that demonstrates an unsuccessful fetch.

* Render the markdown document (since we're fetching markdown after
all).

* Remove vague comment that's not really helping.

* Improve inner_html example

* Include a textual explanation of what the example is doing.

* Run cargo fmt

* Remove 'static lifetime for constant

* Improve suggestion in inner_html example

* move markdown.rs to a common crate

* add description to common Cargo.toml

* PR feedback

* PR feedback

* remove static lifetime annotation
jstarry pushed a commit that referenced this issue Jul 9, 2020
jstarry pushed a commit that referenced this issue Aug 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants