Hyperapp: Idiomatic ?

Created on 1 Mar 2018  路  4Comments  路  Source: jorgebucaran/hyperapp

Hi, new to hyperapp.

Wondering if the below fragment is idiomatic ?

I could nest the action, but if I don't want to, is object spreading an ok solution to return the state tree ?

Any thoughts ?

import { h, app } from 'hyperapp'

import 'tachyons/css/tachyons.min.css'
import './style.css'

const state = {
    env: {
        ip: '127.0.0.1',
        theme: 'light',
    },
}

const actions = {
    toggle: _ => state =>
        state.env.theme === 'light'
            ? { ...state, env: { ...state.env, theme: 'dark' } }
            : { ...state, env: { ...state.env, theme: 'light' } },
}

const view = (state, actions) => {
    const styles = `f2 ${state.env.theme === 'light' ? 'primary' : 'secondary'}`

    return (
        <div class={styles}>
            <span>hello hyperapp ({state.env.theme})</span>
            <button onclick={e => actions.toggle()}>toggle</button>
        </div>
    )
}

app(state, actions, view, document.body)
Inquiry

Most helpful comment

@jbrodriguez My concern about nesting actions is that, even though they receive a slice/partial state, they may need to know about the whole state.

Yes if that happens a lot, consider not nesting the actions in the first place. Otherwise, here's another approach you might consider: https://zaceno.github.io/hypercraft/post/cross-namespace-action-calling/

All 4 comments

Hyperapp does a shallow merging of the object your action returns (a partial state) with the "real" state object, so you don't need to spread the {... state}.

Here is a simplified version:

const actions = {
    toggle: _ => state =>
        state.env.theme === 'light'
            ? { env: { ...state.env, theme: 'dark' } }
            : { env: { ...state.env, theme: 'light' } },
}

Your method of updating the nested object looks good to me. 馃憤

It is certainly a case where a nested action could simplify the implementation, though (at least visually). It's a matter of personal preference, really.

const actions = {
    env: {
        toggleTheme: _ => state =>
               state.theme === 'light' ? { theme: 'dark' } : { theme: 'light' }
    }
}
...
        <button onclick={e => actions.env.toggleTheme()}>toggle</button>
...

Thanks @SkaterDad !

That was helpful !

My concern about nesting actions is that, even though they receive a slice/partial state, they may need to know about the whole state.

This was discussed previously (https://github.com/hyperapp/hyperapp/pull/385#issuecomment-337010722), although I can't find a 'solution', except for implementing top-level actions like in my code sample.

In any case, I'll close the issue.

It's a nice framework, looking forward to experiment more.

@jbrodriguez If you need two actions from different slices to communicate with each other, put those slices in the same parent and add actions to the parent that do what you need.

A new feature coming in 1.2.0 is _subiews_, which like your view function, are wired to the global state and actions. You can access the global state and actions from within a subview.

@jbrodriguez My concern about nesting actions is that, even though they receive a slice/partial state, they may need to know about the whole state.

Yes if that happens a lot, consider not nesting the actions in the first place. Otherwise, here's another approach you might consider: https://zaceno.github.io/hypercraft/post/cross-namespace-action-calling/

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zaceno picture zaceno  路  3Comments

jscriptcoder picture jscriptcoder  路  4Comments

dmitrykurmanov picture dmitrykurmanov  路  3Comments

joshuahiggins picture joshuahiggins  路  4Comments

jorgebucaran picture jorgebucaran  路  3Comments