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.

Introduction

Why mixin needs to specify its namespace in state and actions? The main purpose of mixin with state or actions will be almost always adding these two props under key with name of mixin (because naturally we want to avoid namespace pollution) so what if we scope state and actions in mixin automatically?

Actual behavior

Now it’s working like this: counter | app.

Proposal

I propose that we change a little bit behavior of mixins. It would give more sense if we automatically scope mixin’s state and actions so mixin doesn’t need to use own name inside of itself. Change will be needed in the core of HyperApp where we must store state and actions of every mixin under mixin name. And mixin’s actions must be initialized with scoped state and actions. But if we need global addition of mixin’s state/actions to app (to first level without storing under mixin name) then we can inform app about globals for example by nesting under global prop in mixin (example) which will return mixin structure under “mixin.global.state” or “mixin.global.actions” and in HyperApp will be verification if mixin contains “global” and if so then it will store it immediately to first level of state or actions.

Proposed behavior

After this change would be possible to write mixins like this: counter | app. You can switch between “master” (actual behavior) and “scope” (with proposal) branch for comparison.

For this purpose it would be better to change mixins prop from array to object (key = mixin name) because then we can use mixin’s name as a namespace for storing mixin’s state (state.mixinName) and actions (actions.mixinName). And another advantage would be optional change of mixin’s name so for example if you need use “router” as a key in your business logic and at the same time you need package Router then you can include this package under different name in mixins (e.g. mixins: { _router }).

Summarize

  • Change prop mixins to object.
  • Scope automatically state and actions in mixin.
  • Add some signal for “global” state and actions so you can avoid automatic storing under mixin’s name

P.S.: I’m working on this experiment so later I can send working example.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:1
  • Comments:31 (23 by maintainers)

github_iconTop GitHub Comments

4reactions
MatejBranskycommented, Oct 19, 2017

Hyperapp 0.15.0 solves this in the core with modules. 👍

4reactions
jorgebucarancommented, Jul 3, 2017

Notes

Here is what we are trying to achieve in easy to understand pseudo-code.

This is the app.

app({
 state: {
   color: "Red"
 },
 actions: {
   switch: state => ({ color: "Blue" })
 },
 mixins: { A }
})

Let’s define mixin A.

const A = () => ({
 state: {
   value: 1
 },
 actions: {
   up: state => ({ value: state.value + 1 })
 },
 mixins: { B }
})

And mixin B.

const B = () => ({
 state: {
   flag: true
 },
 actions: {
   toggle: state => ({ flag: !state.flag })
 }
})

As you can see mixins A and B state and actions seem to be isolated from the global state/actions. In fact, the state either mixin action receives is a fragment of the global state.

This, of course, is not how mixins work at the moment. The proposal is to make them work that way.

So, for completion, here is how the global state and actions are updated behind the scenes during init.

For convenience, let’s call the global state/actions objects STATE and ACTIONS.

var STATE = {
 name: "Red",
 A: {
   value: 1,
   B: {
     flag: true
   }
 }
}

var ACTIONS = {
 rename: Function,
 A: {
   up: Function,
   B: {
     toggle: Function
   }
 }
}

Another way to think about this is namespaces.

But this is much more than just a namespace. The real difficulty is to correctly call those actions passing the piece of the global state that corresponds to that specific namespace/scope.

Not every app uses a mixins, so all of this stuff is only relevant if you are using mixins.

I still need to fully grasp all the implications, but basically this allows you to create mixins that don’t need to know how to grab their state/actions from the global state.

It’s also limiting because then there is no way for a mixin to merge something in the top level (probably not a good idea anyway).

This also makes actions extremely convenient to work with in deeply scoped mixins.

Notice how mixins can be nested.

My worry is that this looks a lot like stateful components.

But it isn’t. This is definitely a single state tree.

/cc @zaceno @MatejMazur

Read more comments on GitHub >

github_iconTop Results From Across the Web

Localizing/Scoping a sass mixin - css - Stack Overflow
Mixins use the same rules as sass variables in that if they are nested inside a block of code its not viewable/useable outside...
Read more >
mixin and @include - Sass
Mixins allow you to define styles that can be re-used throughout your ... means it can only see local variables in the scope...
Read more >
scope of function and mixin definitions · Issue #2268 · sass/sass
I use node-sass-import-once to organize my sass mixins and modules in separate files, and make sure dependencies are always loaded correctly ( ...
Read more >
LESS - Mixin scope - Tutorialspoint
Mixins consisting of variables are visible and can be used in caller's scope. But there is one exception, if the caller contains a...
Read more >
Variable scoping | Sass in the Real World: book 1 of 4
In Sass, all variables declared outside of a mixin or function will have a global scope and can be referenced in any Sass...
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