Redux: Redux & NuclearJS

Created on 5 Jul 2015  Â·  7Comments  Â·  Source: reduxjs/redux

Both of these projects seems to have a lot of similarities both in philosophy/implementation and mutual respect for one another (one could even see these projects merging one day?). Since I'm "in the market" for a functional, reactive Flux implementation, what would be the things to consider between the two? What would you say are the advantages of Redux over NuclearJS?

Most helpful comment

Here's why I chose to write Redux instead of using NuclearJS:

  • I don't want a hard dependency on ImmutableJS
  • I want as little API as possible
  • I want to make it easy to jump off Redux when something better comes around

With Redux, I can use plain objects, arrays and whatnot for the state.

I tried hard to avoid APIs like createStore because they bind you to a particular implementation. Instead, for each entity (Reducer, Action Creator) I tried to find the minimal way to expose it without having any dependency on Redux whatsoever. The only code importing Redux and actually depending hard on it will be in your root component and the components that subscribe to it.

NuclearJS has a really nice concept of getters but I also felt that it tries to be “too smart” around performance and I didn't want to make this mandatory. Instead, with Redux, you can achieve similar results by using a library like reselect:

import React from 'react';
import { createSelector } from 'reselect';
import { connect } from 'redux/react';

const subtotalSelector = createSelector(
  [state => state.shop.items],
  items => items.reduce((acc, item) => acc + item.value, 0)
);

const taxSelector = createSelector(
  [subtotalSelector, state => state.shop.taxPercent],
  (subtotal, taxPercent) => subtotal * (taxPercent / 100)
);

const totalSelector = createSelector(
  [subtotalSelector, taxSelector],
  (subtotal, tax) => { return {total: subtotal + tax}}
);

@connect(totalSelector)
class Total extends React.Component {
  render() {
    return <div>{this.props.total}</div>
  }
}

export default Total;

That said, NuclearJS definitely was a big inspiration to me.

All 7 comments

Here's why I chose to write Redux instead of using NuclearJS:

  • I don't want a hard dependency on ImmutableJS
  • I want as little API as possible
  • I want to make it easy to jump off Redux when something better comes around

With Redux, I can use plain objects, arrays and whatnot for the state.

I tried hard to avoid APIs like createStore because they bind you to a particular implementation. Instead, for each entity (Reducer, Action Creator) I tried to find the minimal way to expose it without having any dependency on Redux whatsoever. The only code importing Redux and actually depending hard on it will be in your root component and the components that subscribe to it.

NuclearJS has a really nice concept of getters but I also felt that it tries to be “too smart” around performance and I didn't want to make this mandatory. Instead, with Redux, you can achieve similar results by using a library like reselect:

import React from 'react';
import { createSelector } from 'reselect';
import { connect } from 'redux/react';

const subtotalSelector = createSelector(
  [state => state.shop.items],
  items => items.reduce((acc, item) => acc + item.value, 0)
);

const taxSelector = createSelector(
  [subtotalSelector, state => state.shop.taxPercent],
  (subtotal, taxPercent) => subtotal * (taxPercent / 100)
);

const totalSelector = createSelector(
  [subtotalSelector, taxSelector],
  (subtotal, tax) => { return {total: subtotal + tax}}
);

@connect(totalSelector)
class Total extends React.Component {
  render() {
    return <div>{this.props.total}</div>
  }
}

export default Total;

That said, NuclearJS definitely was a big inspiration to me.

Oh, and of course I had these two other goals in mind that NuclearJS did not satisfy:

  • Everything must be hot reloadable
  • It should be possible to build time travel tools with reevaluation on reload, like in my talk

Thanks for the thorough answer. I've been studying Nuclear's React mixin to understand how I can integrate it into a not-React view layer (in my case, Aurelia). I've also started to take a look at the Collector and CollectorDecorator, but I'm having a time distilling out what's essential. Is there any good documentation or an example about generic view layer integration?

BTW, if I get this figured out, I'd be happy to share the approach for your documentation.

Basically Redux's top-level API is just { subscribe(listener), dispatch(action), getState() }.

Provider makes it available down the React component tree via context. Connector uses subscribe(listener) to listen to changes and read from getState() when a change occurs.

These are the only essential parts.

Okay, good. That's what I was able to deduce from studying Provider and Connector.

I'm closing as it's not really an issue.

Thank you @gaearon for the feedback you provided here, was most informative.

For those interested, Dan provided more insights on that very topic.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

CellOcean picture CellOcean  Â·  3Comments

vraa picture vraa  Â·  3Comments

dmitry-zaets picture dmitry-zaets  Â·  3Comments

cloudfroster picture cloudfroster  Â·  3Comments

jimbolla picture jimbolla  Â·  3Comments