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

Classes and Decorators? #4

Open
be5invis opened this issue Aug 19, 2018 · 2 comments
Open

Classes and Decorators? #4

be5invis opened this issue Aug 19, 2018 · 2 comments

Comments

@be5invis
Copy link

be5invis commented Aug 19, 2018

Just for curiosity, if we use TypeScript decorators, is it possible to turn this:

// Counter.js
export default {
  init: () => ({ count: 1 }),
  actions: {
    down: () => state => ({ count: state.count - 1 }),
    up: () => state => ({ count: state.count + 1 })
  },
  view: (state: State, actions: Actions) =>
    <div>
      <h1>{state.count}</h1>
      <button onclick={actions.down}></button>
      <button onclick={actions.up}>+</button>
    </div>
}

into

export default class Counter {
    @state count = 1
    @action down = () => { return {count : this.count - 1} }
    @action up = () => {return  {count: this.count + 1} }
    render () {
        return <div>
          <h1>{this.count}</h1>
          <button onclick={this.down}></button>
          <button onclick={this.up}>+</button>
        </div>
    }
}
@zaaack
Copy link
Member

zaaack commented Aug 20, 2018

Thanks for your attention. The original purpose of this library is based on hyperapp and try to follow the Elm's API as same as possible via TypeScript. There is no class in Elm but just functions and modules, so we kept this in hydux.

I known classes syntax have many advantages, like really good support in TS, don't need currying to pass state and actions. But if we adopt this syntax in hydux, there will be some problem that we have to resolve:

  1. State and actions of a component are type-safe and pure, and exposed type-safely, this is how we compose components in hydux, pure state and actions can be composed and access in different parent component.

e.g.

// someParentComponent.tsx
import Counter from './counter'

export const init = () => {
  const counter1 = Counter.init()
  return {  
    state: counter1.state,
    cmd: Cmd.map(_ => _.counter1, counter1.cmd)
  }
}

export const actions = {  
   counter1: Counter.actions,
}

export const view = (state, actions) => {  
    return (
        <div>{Counter.view(state.counter1, actions.counter2)}</div>
    )
}

You can find the child component's state, actions and view are all exposed to parent component, this's what we called the Elm Architecture, and also the main differences between redux/mobx, we keep React's fractal architecture even in the single state and logic.

  1. Compose child components without loose type-safety. Not sure class syntax can ahieve this, typescript is really powerful thought. In hydux, each component's state and actions do not just contain their own, but also contain child components' state and actions. To achieve class syntax's benefits perhaps we should keep a component instance tree somehow, so we can access merged state/actions in this instance.

Thanks for your advice!

@Kingwl
Copy link

Kingwl commented Aug 20, 2018

it's very helpful to me!

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

3 participants