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.

Current Behavior

Recently effects and reducers got merged into actions. Now the way to set the state is by returning an object.

Figure 1a

const someAction = (model, data, actions) => {
	return {
		state: 'change'
	}
}

The issue with that is that it makes the return functionality unavailable for (former) effects, which means that it is no longer possible to have actions return some temporary value. This is an important piece of functionality for complex apps.

In addition to that it makes the following patterns harder:

Figure 2a

const actions = {
	example: (model, data, actions) => {
		// since `actions.fetch()` depends on `model.url` the user is forced to add a reducer for this
		// simple example, since `return` would exit the function
		actions.setUrl('https://github.com')
		actions.fetch()
	},
	setUrl: (model, data) => ({
		url: data
	}),
	fetch: model => {/*...*/}
}

Figure 3a

const actions = {
	example: (model, data, actions) => {
		setTimeout(() => {
			// won't work, also needs an additional reducer
			return {
				state: "change"
			}
		})
	}
}

Proposed Behavior

Suppose there’d be a default action. Let’s say setState or set that could be called with a model change. Above patterns would become:

Figure 1b

const actions = {
	example: (model, data, {set}) => set({
		state: 'change'
	})
}

Figure 2b

const actions = {
	example: (model, data, actions) => {
		actions.set({
			url: 'https://github.com'
		})
		actions.fetch()
	},
	fetch: model => {/*...*/}
}

Figure 3b

const actions = {
	example: (model, data, {set}) => {
		setTimeout(() => set({
			state: 'change'
		})
	}
}

Advantages

This has the advantage that any state change is always initiated by a actions.set() call. No more “sometimes return” and “sometimes add a reducer”.

In addition to that it frees return, meaning that you can now do this:

const actions = {
	three: (model, data, {set}) => model.one + model.two,
	print: (model, data, actions) => console.log(actions.three())
}

which is amazing for more complex apps.


Meta

Original issue: What about setState?

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:30 (23 by maintainers)

github_iconTop GitHub Comments

1reaction
zacenocommented, Mar 15, 2017

@jbucaran

we didn’t merge reducers with effects, we simply removed effects and renamed what was left (reducers) to actions

Ok that explanation clicks with me 😃 I now think I better understand how you see it.

… but still: reducers didn’t use to be able to call other reducers. In Elm, Msg:s are something more specific than “just functions” – each one represents a singular way that state can be transformed. Losing this sort of ‘pure’ reducer still irks me a little.

Anyway, I don’t mean to derail this issue with my nostalgia for the “good old days” (2 weeks ago? 😉 )

I just mean to say I (personally) feel like something was lost (“elegance”, “purity”… not sure what to call it), and that I interpret @dodekeract’s suggestion as an attempt to bring back some of what was lost, within the frame of this new architecture.

1reaction
jorgebucarancommented, Mar 15, 2017

‘Overloading’ the return statement with hidden meanings (different things happen depending on what you return) looks to me like an inelegance that should be remedied somehow.

I think it’s pretty simple actually. If I was pushed to compare the current architecture to the original reducers/effects architecture, I would say: if you return something, then it’s like the old reducers. If you don’t return anything, then it’s like the old effects.

In reality, however, here’s how I see the current architecture compared to the original one: we didn’t merge reducers with effects, we simply removed effects and renamed what was left (reducers) to actions, a more broader and reasonable term that boils down to functions.

I don’t see this as hyperapp going out of its way either. Before, a reducer that returned undefined, i.e., didn’t return anything, would cause the view to be rendered and also try to merge undefined with the current model, none of which makes any sense.

Think about it, first, actions behave like the old reducers, we merge their return value with the model. We certainly skip any view renders if your ~reducer~ action returns nothing, as merge(model, undefined) would be useless, but even if we didn’t you could still use them as effects (they would cause a useless view render however).

The only special case is, admittedly, promises, but then everything is “special” about promises in JavaScript land.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Actions · reworkcss/rework - GitHub
Automate your workflow from idea to production. GitHub Actions makes it easy to automate all your software workflows, now with world-class CI/CD.
Read more >
5 Ways to Reduce Reworks and Errors - Device Magic
1. Create a Quality Process. Preventing reworks and errors is more effective than spending time and resources fixing problems after they occur. Your...
Read more >
Why And How To Identify Rework in Business Processes
The Rework Detector adds a new point of view to data analysis. Now you can separate the loop starting activities (triggers) and ending...
Read more >
Tool: Foster psychological safety - re:Work
Manager Actions for Psychological Safety. This guide can help managers think about how they model and reinforce psychological safety on their teams.
Read more >
Rework Procedure for Your Medical Device - GMP Trends
The Code of Federal Regulations (CFR) defines rework as an action taken on a nonconforming product so that it will fulfill the specified...
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