Choo: Rename `send` to `action` in docs & examples?

Created on 8 Oct 2016  Β·  9Comments  Β·  Source: choojs/choo

Saw a lot of work is going on with v4. Very cool!

Just a thought here -- actions are mentioned _a lot_ as a concept throughout the documentation, but don't exist as a word anywhere in the examples. What if we renamed send to action, since that's what it's doing? e.g.

const mainView = (state, prev, action) => html`
  <main>
    <h1>Title: ${state.title}</h1>
    <input
      type="text"
      oninput=${(e) => action('update', e.target.value)}>
  </main>
`

This might help clarify concepts and bring the ideas from the unidirectional architecture chart into the code -- making it easier for beginners to understand and pick up. Since send is always referenced as a parameter it would not change the API at all, just the examples, and I think it would solidify the relationship between concepts and code considerably with one small tweak.

Most helpful comment

@timwis that would break the unidirectional model, and would require the extra done() callback in the views. I think creating a clear boundry between views and logic so far has paid off, I'd be cautious to mess with that

All 9 comments

I guess one caveat is the the createSend() function name would have to be changed too. But if you read through it I think createAction() makes a lot more sense too!

https://github.com/yoshuawuyts/choo#appusehooks

Thanks for kicking off discussion about this; given that a framework is tightly intertwined with vocabulary getting it right is definitely important!

I've got a bit of mixed feelings about renaming send() - I quite like using verbs over nouns for APIs, and send() has a nice ring to it. _"On click send an action"_ would translate to <div onclick=${send('action')}> - it feels good I think.

There's a bit of inconsistency in the API though: views have a send() function that doesn't take a callback. effects and subscriptions have a send() function that does. I was thinking about possibly renaming some calls:

  • views: have a send() function that sends off an action
  • effects: have a call() function that sends off an action and calls back when it's done
  • subscriptions: have a call() function that sends off an action and calls back when it's done

Now that we're touching on the topic of subscriptions anyway; I was wondering about perhaps changing it from a call() to a send() to put it more in line with how views behave. But then again: that would move even more logic into effects, and I feel real world apps have about 90% of their logic living in effects already. But that might perhaps be a different topic.

On the matter of calling action action; perhaps a different name might make sense. Some words might be:

  • task: as in a task that goes into the scheduler and is resolved. Analogous to the browser's task system
  • message: as in a message in the message queue. Analogous to Erlang's messages between processes
  • job: uehh, another word I guess?

Not sure if changing names would have any benefit tho. I feel they're all very similar to one another, and in the end we should just choose something and run with it. It's what we did with model vs store anyway. Keen to hear different thoughts on this though; as getting vocabulary right is indeed something we should pay careful attention to.

p.s. I got a bit caught up and forgot to reply to part of your post. Another reason why I'm not entirely convinced action should be an actual thing in the API is because we're not doing the same thing with views either. All we got is router and choo/html. The word view only exists as a concept, but not as an API - I don't reckon it's confusing for people though. But yeah, just a thought (:

What if the send that views get also have a callback as the last param?

@timwis that would break the unidirectional model, and would require the extra done() callback in the views. I think creating a clear boundry between views and logic so far has paid off, I'd be cautious to mess with that

Thanks for your thoughtful reply @yoshuawuyts! I think the main pain point from the perspective of an uninitiated noob (as I was not too long ago) is mentally mapping the surface API to this:

 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
 β”‚  Subscriptions ──     User ───┐
 └─ Effects  ◀──────             β–Ό
 β”Œβ”€ Reducers ◀─────┴──Actions── DOM ◀┐
 β”‚                                   β”‚
 β””β–Ά Router ─────State ───▢ Views β”€β”€β”€β”€β”˜

So I think it's not totally clear how actions interact with all three of the (insert group noun for subscriptions, effects, reducers) simultaneously. I spent some time searching for the word "action" early on to fully understand how it related to subscriptions, effects, and reducers, and just had to dive in and test it myself to really grok the conceptual model. I think now that there's a send(actionName, data?[,callback]) API definition in the readme it's a little easier to grasp. I might submit a PR trying to flesh out a general explanation of Actions under Concepts to go with the other big concept rubrics.

One detail that is a little fuzzy is:

An action can trigger a subscription, an effect, or a reducer. Can one action trigger all three at the same time? (In practice the answer seems to be no, I think it will only trigger the first match it finds, but the ordering seems arbitrary and multiple action name matches don't produce an error)

Also re:

On the matter of calling action action; perhaps a different name might make sense.

I think action is a good word; it accurately represents a user performing an action.

I might submit a PR trying to flesh out a general explanation of Actions under Concepts to go with the other big concept rubrics.

Ohhh, that'd be amazing! - I'd be happy to review / comment / assist with that, getting docs from a learner's perspective would be amaze


An action can trigger a subscription, an effect, or a reducer.

Uh oh, that's def a typo. subscriptions cannot be triggered, they run and do their thing. Only reducers and effects can be triggered. Also yeah: a single action can only trigger a single handler. In the past it used to be possible to trigger both an effect and reducer with the same action, but that turned out to be a very bad idea haha.

Thanks heaps for taking your time to dig through this!

In this case maybe updating the docs with "An action can trigger either an effect or a reducer."?

Closing because choo@5 will introduce a new API. See #425 for the merged PR. Thanks!

Was this page helpful?
0 / 5 - 0 ratings