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

Proof of Concept : React style state hooks in seed #255

Closed
rebo opened this issue Oct 20, 2019 · 4 comments
Closed

Proof of Concept : React style state hooks in seed #255

rebo opened this issue Oct 20, 2019 · 4 comments

Comments

@rebo
Copy link
Collaborator

rebo commented Oct 20, 2019

Feel free to delete this is if this is not the appropriate place to put this for discussion.

Was bored this afternoon and wanted to see if I could get react hooks style 'per-component state' working in seed.

It definitely is not the Seed style but something like this might be nice for lighter weight components that don't need the fully Message architecture.

It seems to work but I have not really tested it at all.

Sample component:

#[topo::nested]
fn example() -> Node<Msg> {
    // Declare a new state variable which we'll call "count"
    let (count, set_count) = use_state(0);

    div![
        p![format!("You clicked {} times", count)],
        button![
            input_ev("click", move |_| {
                set_count(count + 1);
                Msg::DoNothing
            }),
            Click Me
        ]
    ]
}

vs the reactjs:

import React, { useState } from 'react';
function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

Here is the POC : https://github.com/rebo/proof_of_concept_seed_hooks

@MartinKavik
Copy link
Member

Well, I like to use only Elm-like patterns, but let's be pragmatic - I see some reasons / places where we can use stateful components:

  1. For lightweight components (your reason). However it can be easily abused to create Frankenstein applications.
  2. To attract React developer - they wouldn't have to learn Rust and Elm architecture at once.
  3. To create custom elements which wraps JS (i.e. code blocks managed by highlight.js).

So I basically like your idea and I think that it would be nice to have it as a standalone crate, but I see some drawbacks with the current implementation:

  1. I assume that if you try to integrate your stateful components into a standard Seed app, it won't work because Seed's VirtualDOM will be fighting over DOM with those components.
  2. WASM file will be be probably bigger.
  3. Debug two runtimes and architectures can be a nightmare.

When you have another boring afternoon, you can look at web components. WCs should eliminate problem n.1 with Shadow DOM; it's the native browser feature so a lightweight library should be enough to resolve problems 2 and 3.
Some links to start:

@rebo
Copy link
Collaborator Author

rebo commented Oct 21, 2019

Hi Martin

Thank you for your insightful comments. Yes I pretty much agree with your comments and consider this attempt an experiment rather than a serious attempt at a performant and robust implementation.

With regard to the virtual dom getting in an inconsistent state I am not certain that this is the case. My understanding is that if the view function is run then the various state stores should be updated/accessed. I think it should be that the order of the view code execution is what defines the state contexts and therefore hopefully virtual dom mutation wont be an issue. I am probably missing something here though!

Defo think debugging could be an issue and that there are possibly two run times involved a problem.

I love The Elm Architecture it's really clean and I feel like I always know what is going on. However when I want just a tiny change and I know I have to edit at least 3(and possibly up to 6 ) locations to effect it I get a little fed up.

I will have a look at webcomponents and thanks very much for the links and research.

@MartinKavik
Copy link
Member

VirtualDOM - I'm looking at the example code and I think you are right. At first glance, I thought Moxie is more invasive, but it looks like you basically use it only as the global store (if I don't overlook something). So you can probably ignore my previous comment about VD.

So maybe it's the one way to go and in combination with WCs, you can even modify DOM independently of Seed.

I suggest to continue with discussion in your repository (https://github.com/rebo/proof_of_concept_seed_hooks) and report back once we have some news.

@rebo
Copy link
Collaborator Author

rebo commented Oct 21, 2019

Ok cool, Ill tinker more in the POC repo and let you guys know how it develops later.

@rebo rebo closed this as completed Oct 21, 2019
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

2 participants