question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Idea for hyperapp router

See original GitHub issue

I want to add simple router to hyperapp, I thought that I use something like react router.

I can use url hash as state property, but I need to access action from outside of app, is there something like

init actions:

actions: {
  init: function(state, actions) {
    window.addEventListener('hashchange', function() {
      actions.url(localhost.hash.replace(/^#/, ''));
    });
  },
  url: function(state, actions, url) {
    return {url};
  }
}

Second I want to create Route widget but I need to have something like children (Something like angularjs transclude or react props.children)

const Route = ({path, url}) => {
    if (match(path, url) {
       return ( children );
    }
}

so I can use:

app({
  state: {url: localhost.hash.replace(/^#/, ''))},
  view: (state, actions) => (
     <div>
       <Route path={"/user"} url={state.url}>
         <p>user</p>
       </Route>
       <Route path={"/category"} url={state.url}>
         <p>category</p>
       </Route>
     </div>
  ),
  actions: {
    init: function(state, actions) {
      window.addEventListener('hashchange', function() {
        actions.url(localhost.hash.replace(/^#/, ''));
      });
    },
    url: function(state, actions, url) {
      return {url};
    }
  }
});

are those two things possible with hyperapp?

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:30 (22 by maintainers)

github_iconTop GitHub Comments

1reaction
SkaterDadcommented, Jul 17, 2017

I agree this could be closed. Also not sure it’s worth migrating any of this to the router repo.

What this discussion highlights to me is that JSX makes things awkward since you’re forced to write your functions in a very specifc way. I don’t personally use it, so it’s hard for me to relate. I see the appeal, but it seems restrictive.

@jcubic 's example of <Navigation state={state} actions={actions}/> could just be Navigation(state, actions) in vanilla JS land.

Here is a plain JS example from my own router experimentation. A RouterView function, used in a Layout function. There’s a predefined routes array like you’d see in other frameworks. The same philosophy could be adapted for RR4-style routing, I think, if you expose the match function to the view.

function RouterView(state, actions) {
  const route = routes.filter(r => r.path === state.router.match)[0] || {}
  if (route.view === undefined) return null
  return typeof route.view === "function" ? route.view(state, actions) : route.view
}

const Layout = (model, actions, children) => {
  return h('div', { id: 'layout' }, [
    h('header', {}, [
      h('h1', {}, 'Site Name'),
      h('nav', {}, [
        Link(actions.router, { to: '/', text: 'Home', attrs: {}}),
        Link(actions.router, { to: '/about', text: 'About', attrs: {}}),
        Link(actions.router, { to: '/about/1', text: 'About 1', attrs: {}}),
        Link(actions.router, { to: '/about/1?test=[2,3]', text: 'About Array', attrs: {}})
      ])
    ]),
    h('main', { class: 'page' }, RouterView(model, actions))
  ])
}
1reaction
zacenocommented, Jul 16, 2017

@jbucaran: I (speaking only for myself, of course) think we can close this here, but don’t think we need to move anything to the router-repo, because as of yet we don’t have anything concrete.

But in saying we can close the issue, I don’t mean the discussion should end – quite the opposite! (Is it possible to migrate an entire issue with all the discussions et c from one repo to another?)

The basic idea of mapping routes to state rather than views is sound, but so different from the official router that it’s probably best implemented as an unofficial alternative.

However, I think I’ve found a significant problem with implementing a react-style router for hyperapp (with <Route match="... style components). And that is: JSX translates the component tree into a tree of h(...) calls, and these calls will be executed depth-first (that’s just how javascript works). So that means that for every route – even all the ones that don’t match, the child-trees will have to be built. So all the “pages” of an app must be built (even if we don’t end up showing them) for every state update. That obviously doesn’t scale – and will probably be riddled with runtime errors if you expect state vars to exist that don’t in unmatched routes.

I honestly don’t know how react-router get’s around this problem. Probably they can get around the issue thanks to their component architecture somehow. I imagine a react component is kind of like a HyperApp-app in itself, managing it’s own vdom.

The best I’ve been able to come up that is almost the same:

Instead of this:

...
<Router match="/users/foo">
  <UserPage user="foo" />
</Router>
...

you have this:

...
{emit('router:match?', '/users/foo') && <UserPage user="foo" />}
...

It works because by using the && operator, javascript will skip evaluation of the the right hand operand if the left hand is falsy.

This also means we can’t use the “nested matching” or whatever it’s called (where you can match on the first part of the route, and then in the child match on a follwing part, and below that another part et c… That’s what lets the react-router do that cool “recursive routes” trick. But I don’t see how that’s possible in hyperapp (without tossing performance and scalability completely out the window)

Read more comments on GitHub >

github_iconTop Results From Across the Web

A Quick Introduction to Hyperapp - DigitalOcean
Hyperapp is a very small micro-framework used to build declarative web applications. It's only 1kB in size and the API is similar to...
Read more >
Actions · jorgebucaran/hyperapp-router · GitHub
Declarative routing for Hyperapp V1 using the History API. - Actions · jorgebucaran/hyperapp-router. ... Automate your workflow from idea to production.
Read more >
Postix II: Multipage app with routing, in Hyperapp - Medium
Postix II: Multipage app with routing, in Hyperapp. In the last story, we set up a development environment for our app and created...
Read more >
Hyperapp – A tiny framework for building web interfaces
A router for Hyperapp: https://github.com/mrozbarry/hyperapp-router. I have a handful of older youtube videos regarding v1, you can check ...
Read more >
@hyperapp/router examples - CodeSandbox
Learn how to use @hyperapp/router by viewing and forking @hyperapp/router example apps on CodeSandbox.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found