Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Things to learn in React before using Redux (robinwieruch.de)
370 points by callumlocke on July 20, 2017 | hide | past | favorite | 104 comments


My first project with React was a mess, mostly because of Redux. Not because it's bad, but because the lead dev was adamant about using something Flux like. First we had Flummox, than he rewrote everything in a week with Redux, that was 2 years ago, before Redux had sane async helpers.

In my current project (where I'm the lead, haha) I'm trying to got state/props all the way.

I think for most apps it's more than enough AND it's easier to get started for new devs.

React is really easy. I mean coming from Ember and ExtJS, its API is a walk in the park and you can get really far without extra state management.

One thing that is important for this approach, minimize nesting.

You don't want to pass down everything from the app, to the screen, to the list, to the item. etc.

Instead of doing:

    <List items={items} />
do it like that

    <List>
      {items.map(i => <Item item={i}/>)}
    </List>
No nesting of screens (top-level components), no (hidden) nesting of components. This may seem kinda strange, because the first example has no dependency to the Item component, but it gives the component that uses the List direct access, which simplifies props-passing immensely.

This doesn't work for all apps, but it's a good starting point.

I ended up with 2 folders, screens and components, that are both simply flat lists of component files.


Also, when you do use Redux, as in your nesting example don't pass props through components that don't have any need for them except they propagate the prop to someone else. It's absolutely fine to connect() a component deeper in the hierarchy. Passing everything down is an anti-pattern with Redux, separation of concerns still applies and the props of a component defines the API, don't clutter that API with unrelated things.

Components only receiving props that they themselves need has kept things clean in our massive codebase, and allows you to effortlessly move things about and easily re-use components wherever it makes sense.


Yep, absolutely. See the Redux FAQ entry on "connecting multiple components" for more info [0] . I also discussed how connecting more components affects performance in my blog post "Practical Redux, Part 6 - Connected Lists, Forms, and Performance" [1], and there's many additional articles that discuss connected components and performance concerns as well [2].

[0] http://redux.js.org/docs/faq/ReactRedux.html#react-multiple-...

[1] http://blog.isquaredsoftware.com/2017/01/practical-redux-par...

[2] https://github.com/markerikson/react-redux-links/blob/master...


I don't agree with the view that a component doesn't need a prop "itself" if it "only" passes it on to a child component. That child component is a part of the parent. If one decided that e.g. the child is too simple to warrant to be its own component and inlined its render() content in the parent instead, suddenly its used props would be needed by the parent "itself".

Another thing to consider is that one tightly couples components to stores when connecting. So reusability of these components is hampered.


If was my understanding that if a component has a prop which changes, even if that prop is passed down the tree, the component will still update.

This is one way I use redux, the connector watches for changes in state and then updates the component directly, rather than passing props down the tree.


I partially blame every tutorial and contrived example of how you should use Redux. When first starting with React & Redux I spent some time thinking of where and how I should use Redux.

Being that I was new to both, I didn't have any ingrained best practices, and it was hard to find any best practices around when to use redux.

Every example seemed to use it for everything, which seemed insane to me in a real web app. I could see that the size and clutter would grow terribly, and for no obvious benefit.

Your example above is similar to how many component libraries work (where you need to give the user flexibility).

In a dashboard app, I'll make good use of Redux because there are often sets of data you revisit in different ways.

In a more directory-like site I've recently built I use it to keep track of the logged in user information and high level information that dictates your experience (like user location), but nothing else.


> I partially blame every tutorial and contrived example of how you should use Redux.

Partially? No. The culture of side projects/GitHub/blog post had led people to over engineer their learning materials and side projects to look as employable as possible. Why make a todo list with just React when you can use Redux in it too and put it in your resume?


He he true.

When I do a side project I often want to do fancy stuff and blog about it.

When I get paid for my work, I try to keep it simple, because I fear I could end up with too much intermingled stuff I won't understand anymore after a few months.


Wanting to do fancy stuff for a side project is understandable. I'd prefer my team do that, so they can learn new stuff - and only bring the techniques/tools that actually work to paid projects.


For what it's worth, my links list has a very large section of articles on Redux architecture and best practices: https://github.com/markerikson/react-redux-links/blob/master... . Mapbox's post on "Redux for state management in large web apps" is particularly good: https://www.mapbox.com/blog/redux-for-state-management-in-la... .


I try to keep it as simple as possible.

But for complex dashboards I would probably use some observable based solution.


I've been doing React for a while now and I've ended up with the same structure: 2 main folders.

One of them in the base components, which are in folders grouped by their corresponding REST service endpoint (so if you have 'Foo' and 'Bar' db tables, and API's, then I have 'Foo' and 'Bar' folders inside my 'components' folder.

The other folder is my views. It's more of the integration layer for all of my components. Since views typically correspond to a page route, that's where most of my react-router stuff is. It also is where I call the react-redux 'connect' HOC, to get data that is fed down into the components.

So far it's working pretty well for me. I think it works great for a medium-size type of app.


In this kind of setup, I'm wondering how you handle events that happen outside of the component?

Let's say you have a background function, created with setTimeInterval, which after some time update an item. With Redux, you could dispatch an action UPDATE_ITEM, which would modify the items, and in turn update the connected component.

However, without Redux how is your component going to know about this item update and update the list? Do you use some kind of event listener/dispatcher?


You have a root component. Run the interval within that component where you have access to state.


That's essentially redux: root state.


If that was "essentially redux", redux would have no reason for existence.


Except for the fact that it drastically lowers the amount of manual props passing you have to do, and allows you to achieve much better separation of concerns. It is essentially Redux, only much worse the more complex your app is.


> It is essentially Redux, only much worse the more complex your app is.

so... not at all like Redux then. C# is essentially Python except it has different syntax and static typing.


The entire Redux library is something like 300 lines of code, most of which is sanity checks. It is basically the same thing as having one root component handle all your state, it just adds a tiny bit of magic for convenience. If you're comparing that to using a completely different language, I encourage you to learn more about how Redux actually works, because it's really very simple.


It literally IS having a root component manage state. That's what the Provider class does (enables connect() to populate via a Redux store in context).


I understand Redux, have used it many times and have read the source code. I don't understand the argument that it is "basically is the same thing as having a root component handle all your state".

It's that plus actions, reducers, dispatcher, middleware, and HoCs for connecting components to global state. So it's not basically the same thing at all.


Actions, the dispatcher, and reducers are effectively a few in/out functions around a thing stuffed into the React context when used by react-redux. You're way overstating things.


And if it's in a module outside the component tree?


As I said, my approach isn't a one size fits all.

At the moment I do React-Native projects, where every app is self contained. On the Web you often have more mashup.

But the approach still works for most Web UIs too, just not for all.


That approach may minimize props passing, but it also is going to cut down on chances to use `shouldComponentUpdate` to avoid unnecessary re-renders and improve performance. Depending on your app, that might not be an issue, but it's something to be aware of.


It's exactly the opposite. You want to make your props as specific to the component as possible to minimize re-renders and pass-through of props causes unnecessary work.

<List items={items} /> will re-render (or at least completely unnecessarily re-evaluate shouldComponentUpdate) the List itself whenever any item has changed.

<Item item={i} /> with a shouldComponentUpdate or better yet React.PureComponent will only re-render the single changed item.


I think we're sorta saying the same thing, but in different ways.

If you have that separate `<List>` parent component, you can apply `sCU` there so that it only re-renders when some of the items have changed, and not when other parts of the application update.

If you don't have the `<List>`, the parent component will always re-render and always at least start the render lifecycle process for the `<Item>` components, but they can also implement `sCU` to skip the actual re-render.

The most optimized approach is to have normalized data in Redux. The parent component should retrieve an array of item IDs in its `mapState` so that it only re-renders when an item is added, removed, or reordered, and render children like `<Item id={itemId} />`. The `Item` components should be connected as well, and use their `mapState` functions to look up the corresponding item from the Redux state by ID. That way _they_ will only re-render when their specific item has changed.


better yet - don't create functions, especially inside a loop, in your render function,

getItem = i => <Item item={i}/>

...

<List> {items.map(getItem)} </List>


How will you solve two components deep down different branches that share state?


for shared state I used localStorage/AsyncStorage and added an event emitter to it.


What about scenarios where that's unavailable? E.g. Safari in private browsing mode?


I use them for persistence, so state is kept between visits.

But in private mode I'd simply use an object as key-value-store.


I'd rather use Redux without React than React without Redux. Sure there's some boilerplate but we use typescript so the redux boilerplate seems trivial in comparison.

Redux keeps your app _simple_. That's not the same as easy. It means that you can reason about your app as it grows and new features are added. When you run into problems like: this page is taking too long to load because we do calculations x, y and z on the server to push the data to the app. But z takes forever to compute and makes the initial page load painful. With Redux, you can move z to an async endpoint and just load x and y on page load (put the component that needs z in a loading state). Then, fire an ajax request when the component mounts to get z. When that call returns, it updates your store and the component that needs z transitions from loading to loaded.

I took me a couple of hours to do the above in a Redux app and decrease the page load from 2 seconds to 300ms. And it didn't add complexity to the app that would make it difficult to maintain. I don't even want to think how long that refactor would take if the state had been managed with React.

And ... don't even get me started on how easy -- and fast -- it is to test a Redux app. Zero side-effects means zero setup and teardown between specs.


The rush to use Redux for every React project is one of the most annoying parts of the React community; using a tool just to use it, before understanding if you need it or not. This article summarizes a lot of good points.


Agreed. Until recently, my team was responsible for most of the official IBM Watson service demos, and we standardized on React for those and built up a nice library of react components[1]. None of them used Redux, though, because in general it just wasn't needed.

When we handed off responsibility of these demos to the individual service teams, we wrote up guidelines that specifically recommended React but not Redux - with the logic that if the demo is getting to a point where Redux is providing value, then it's probably too complex for a demo.

Our new project is a more involved web app that includes lots of state, shared across many different components, and we're making great use of Redux there.

[1]: https://watson-developer-cloud.github.io/react-components/


One of the things I find hardest with redux is to make reusable components (across projects), as they have to be added to the state tree somewhere, and then connected. With nested components you may get implicit dependencies on where in the tree it should be. All this makes it very cumbersome.

So even though most of our apps use Redux, the reusable parts use setState as they then can be completely independent.


Yeah, that is a tradeoff - globalized state makes a lot of scenarios easier, but does make complete encapsulation and reusability harder.

Most of the third-party "Redux-connected component" libs I've seen provide a reducer that they expect to be added to the root of the state tree under a specific key name. Works, but it's not ideal. I've seen a few that let you provide a selector or key name when you initialize the library, so that the library is more flexible in how it's connected.

There's been a lot of discussion of various approaches for implementing fully encapsulated/reusable Redux-based React components in Sebastian Lorber's "Scalable Frontend with Elm or Redux" repo [0], and my links list has a section of additional articles on the topic of encapsulation with Redux [1]. My Redux addons catalog also has a large section for libraries that implement some form of per-component state or component encapsulation in Redux as well [2].

So, it's not impossible, but it does take work and there are tradeoffs either way.

[0] https://github.com/slorber/scalable-frontend-with-elm-or-red...

[1] https://github.com/markerikson/react-redux-links/blob/master...

[2] https://github.com/markerikson/redux-ecosystem-links/blob/ma...


Yea, our new project has a lot of 'container components' where there is a parent component that connects to redux (and react-i18next) gets all of the data & translated text, and then passes it to a child component that is just a regular stateless component that could be easily re-used (and tested!)


These look great! Thanks for sharing.

Also, I like the idea of loosely enforcing against a state management library to cap demo sizes.


> annoying

I like React's ethos of avoiding complexity until you need it, but these smug attitudes are starting to get really tiresome.


I'm not sure I'd characterise the attitude of avoiding additional dependancies until you know you really need them as smug...


The smugness is when you classify a bunch of other people as annoying as if they are incapable of making their own technical trade-offs. "Wake up, sheeple!"

I use Redux on just about every React project because none of my projects are toy projects. And I'm not just doing it to annoy OP.


This summarizes everything about the JavaScript ecosystem, so it shouldn't really surprise React users that there is no logic behind the community's behavior.

People have finally succeeded in making JavaScript an important development platform by sheer force of will, insisting that JavaScript must become important in order to justify their adoption of the fad. Before this critical mass was attained, there was no real reason to use JS whenever the option was available, and virtually everyone who adopted Node.js and friends was doing it "just to [do] it", in service to the fad kicked off by Google's promotion of Chrome/V8.

Consider that prior to V8, JavaScript was so disliked that the only way to get someone to read a book about it was to name it "JavaScript: The Good Parts". The coder would be surprised to hear that anyone thought JavaScript had any good parts, and would want to figure out what they were, so that his/her days spent in client-side hell would go just a little smoother.

Then Google released Chrome with V8, some people thought this meant JavaScript was cool now, and it's snowballed from there.


Or you know, instead of that content-less juvenile rant, we could actually talk about the merits and the disadvantages of JS as a platform like real software engineers.

For example you've missed facts like:

1) Javascript as a language is not really that worse or better than any other popular language. C++ has its complexity issues, C has its undefined behavior and foot-guns, PHP, Python and Ruby have their share of warts, Java has slow progress and the crappy over engineering ecosystem, etc.

It's a dynamic language with crappy coercion rules and a few bad decisions, but also great expressiveness.

2) Javascript has great vendor support, and the fastest dynamic JITs and interpreters bar none, not from one, but for 4 major vendors (Apple, Google, MS and Mozilla). Python, PHP, Ruby, et al don't even come close, even with things like PyPy.

3) Javascript is the default language of the web, the most popular delivery platform today.

4) Javascript has huge library support and tons of packages.

5) Javascript has incorporated lots of advanced concepts (for popular, non-academic languages), from generators and proxies to async/await.

>Then Google released Chrome with V8, some people thought this meant JavaScript was cool now, and it's snowballed from there.

Webkit, v8 and Mozilla's JS JIT were released within months of each other, and have been in work for years before. So this has nothing with Google releasing v8 -- the industry in general wanted faster JS execution. In fact TraceMonkey (Mozilla's JIT) was the first to be released.

If any Google action was relevant to this, it was the popularization of AJAX (which MS introduced) through apps like Gmail that set the future direction for the web.


The "contentless" "juvenile" rant matches my memory of the JS scene at that time.

And while certainly the JS scene nowadays is bigger, it is the opinion of a lot of veteran devs that the scene is a mess and that people are crazy.

It's taken a decade for JS to mature as a language and community to even be considered at-parity for C, C++, Python, or Ruby. Equivalence didn't even enter the picture until recently.

Why is it most newbie-level training materials and most language discussions nowadays seem to center around products ("React", "Redux", "Angular", etc) than techniques? How ironic given the algorithms fetish that is so common in hiring.

How many of these devs can function without a framework? What does that say about the choices made by the community?

What's funny is that JS -- even ten years ago -- wasn't that bad of a language (weird, definitely, but I wouldn't call it bad); unfortunately it was strapped to various messes of HTML engines and competing standards. JavaScript hell ten years ago was shimmying browser features and figuring out how to do that thing that jquery replaced with $(document).ready(). Fighting against the language itself was much less common.


>And while certainly the JS scene nowadays is bigger, it is the opinion of a lot of veteran devs that the scene is a mess and that people are crazy.

Well, if those veteran devs need to invoke widespread psychological problems ("people are crazy") to explain something, shouldn't they take it as a sign that they have a non-explanation?

Besides, opinions are like kidneys. Everybody has at least one.

>It's taken a decade for JS to mature as a language and community to even be considered at-parity for C, C++, Python, or Ruby. Equivalence didn't even enter the picture until recently.

So? You think C, C++, Python or Ruby did that in less time? Ruby, for example, was pretty much non-entity on the programming landscape until Rails emerged. C++ took a decade to be adopted for mainstream programming, as did C.

>Why is it most newbie-level training materials and most language discussions nowadays seem to center around products ("React", "Redux", "Angular", etc) than techniques?

Because the techniques have been long established and there are countless existing tutorials about them that don't go out of relevance (so no need to write the 1000th e.g. module pattern tutorial).

>How many of these devs can function without a framework?

Pretty much everybody?

>What does that say about the choices made by the community?

That they solve common problems (they all make web apps) and have the good sense to not implement the same wheels from scratch every time?

>JavaScript hell ten years ago was shimmying browser features and figuring out how to do that thing that jquery replaced with $(document).ready(). Fighting against the language itself was much less common.

Who "fights against the language itself" today?


>Who "fights against the language itself" today?

It is true that now, 22 years after JavaScript emerged as a toy language to allow people to do simple UI tricks like creating alert boxes, and 8 years after people started trying to shoehorn it into the backend for GCool Points, JS has finally started to adopt some useful features. ES6+ address most of the glaring omissions, and writing a script in JS/Node now doesn't feel too much different than writing a script in Python or Ruby (though much more build infrastructure is required; JavaScript is anything but native outside of the browser). Bolting on those features that have been available in other languages for much longer is a big accomplishment from the ECMAScript people, so props to them.

But there are still many instances of people "fighting the language" in the practical sense (the sense that matters). Two main exhibits: Node's "harmony" feature release model that requires the VM to be run with certain flags to enable certain syntax (much worse than Python's `from __future__` model) as well as Babel's entire existence and widespread usage.

I don't know how often you use other languages, but JavaScript is the only platform where I have to run my code through a chain of slow, third-party transformers just to use simple language features like constants with confidence.

Separately, the standard lib is bare and implementations remain inconsistent, requiring everything to be built on struts like lodash and jQuery (with tons of random dangling accouterments pulled from random GitHub repos, a la `left-pad`) that paper over JS's major pain points and general impracticality. Other scripting languages have convenience libraries and wrappers, even alternative implementations, but nothing else goes to the extremes we see in npm, where it's quite common to pull in single convenience functions as libraries.

While these things may not be quite fighting the "language" from the stringent academic perspective of the ECMAScript spec, they do represent practical constraints on virtually all real-world use. Just as you'd be crazy to try to use JavaScript without jQuery back in the day, you'd be crazy to use it now without the huge amalgam of crap people have developed (babel, lodash, webpack, yarn, etc.) because they are so inexplicably committed to shoving the square peg of JS through the round hole of server-side programming.


>I don't know how often you use other languages, but JavaScript is the only platform where I have to run my code through a chain of slow, third-party transformers just to use simple language features like constants with confidence.

That's because it's also the only platform that supports running your code in 4+ different top-class browser engines, in different browsers by different vendors and reaching 5+ billion people. And it's only needed for that.

For running your scripts like you'd do with Python, just use the latest node version, and skip Babel.


The intent was not really to get into a detailed deconstruction of JavaScript, it was just to comment on the fad-chasing behavior of the JavaScript subculture, as a follow-on to the parent poster's recognition of this within React users.

I don't understand how any person can pretend that everyone was excited about the "promise" of JavaScript back in the day; you'd have to be relatively new to the scene to earnestly believe that, and as a prominent HN poster whose posts I usually enjoy, I know you aren't. This must be some reverse-psychology thing where you're trying to convince yourself that the emotional fad-chasing was in fact merit-based.

Your points are all backwards-looking. I've already conceded that JavaScript is a major/important platform today and I've accepted that I need to use it in various new ways besides basic DOM manipulation, regardless of the deep sadness for tech culture incurred by doing so. Now that Node.js has ridden the hype train for 8-ish years, there is "great vendor support" and "a huge library".

For the sake of argument, we'll gloss over the facts previously mentioned that a) as "the default delivery platform of the web", JavaScript is still massively constrained, and it's much easier to "deliver" backend applications with a real server-side language; and b) that this "huge library" includes many things that would be part of the standard library in a better-managed language, and that there are a great many undesirable side effects to the npm model of allowing random GitHub users to control huge dependency chains (from both a security and a QA perspective; cf. the left-pad fiasco).

Before V8, even JS inventor Brendan Eich spent much of his time offering excuses for and acknowledgements of its major inadequacies: "I only had 10 days!" and "At least it's not VBScript!" being the primary responses. I don't want to diminish Eich's herculean efforts because they truly are impressive, but the point is that no one pretended that JavaScript was the kind of thing that you'd want to use in any context where it wasn't mandatory. This is very unlike Python, Java, or most other professional-grade languages.

>So this has nothing with Google releasing v8 -- the industry in general wanted faster JS execution.

V8 was revolutionary because it took JavaScript from one of the slowest languages around to the nearly-the-fastest dynamic language (vying with Lua for the crown). The demand was there so that browsers could become a platform for more intensive client-side applications like 3D games. Nonetheless, without Google's propaganda machine turning its gears, V8's announcement would've been relegated to the same small group that followed the release of other JS VMs.

It is completely due to the "I'm cool like Google too!" mentality (which has had massive influence on tech over the last 10 years) that Node.js got any traction whatsoever. Node.js made its V8 backend one of its primary marketing points to reinforce that association and make people believe that using Node.js was like using a super-cool Google-fied JavaScript instead of the normal, boring JavaScript you knew from the past.


Javascript is important because it runs on billions of devices - more devices can process javascript than any other language. Being the most used programming language in the world makes it an important development platform by default.


While it may be true that JavaScript has had a large installed base for many years, that installed environment was only capable of operating within the context of a single page load, as long as the browser was open and active, and really was only useful for manipulating the DOM (and JavaScript was a sorry platform even within that ultra-narrow scope).

Node.js changed things by making the platform available on the backend, allowing programs to live longer, but the notion that JS was "important" as a general development solution is incorrect. It certainly was not the "native" or obvious solution for anything beyond manipulating page UI, and this remains the case for the overwhelming majority of the "billions" of devices with JS execution environments. It is still harder to configure Node.js for use on a server than something like PHP.

When I say an "important development platform", I mean that from the perspective of practical use of the technologist, in the sense that the platform is can be expected to host projects that are recognized as clear leaders within a generally applicable space, strongly motivating adoption of the underlying development platform if not already adopted.


As usual, this is an excellent article by Robin. Well-written, and full of great information.

It's worth noting that both the React and Redux teams (including Dan Abramov and myself) agree that you should focus on learning React first, and _then_ learn Redux. That way there's fewer new concepts and terms to learn at once, and once you understand React, you'll have a better appreciation for what kinds of problems Redux can help solve. That's not to say you _can't_ learn them both at once, just that it's the suggested approach that will work best for most people.


As a general rule do not use `this.react` inside `setState({ ... })` - this will cause you problems eventually due state updates being async.

If you need to use state to set new state, use functional callback instead - https://facebook.github.io/react/docs/react-component.html#s...


Worth a read. It summarizes in one place much of what I learned bit by bit from various other articles.


I wish React would come with a standard way to handle Ajax (or a convention or semi-standard library would emerge). (Edit: "comes along" in the sense that immutability-helpers, redux and create-react-app come along with react. I'm not proposing to add anything to the react module. I'm not the world's best expert on react, but before downvoting can you please assume I know a little bit of what I'm talking about?)

Something that:

- Can fetch JSON according to criteria from an API

- Caches stuff locally (just in memory, or in local storage) in case of duplicate calls

- Deals with multiple concurrent calls, and merge them (e.g. fetching 1 and then 2,3,4 before 1 finishes -> either cancel 1, or wait until it finishes, and then fetch only the last requested item.

- And all the stuff I can't think about right now, like cancellation and timeouts

Plug your pure component into one of these, tell it about your API, and you're done. It's really error prone to write these containers yourself. And I think Redux doesn't really help much with Ajax.


React _is_ only a view library. It shouldn't have any thing to do with things like Ajax - that's part of what makes it simple to work with l. It does one thing and does it well. It doesn't even seem to be the responsibility of Redux, which more so is consider with prescribing _how_ data and actions flow through your system, not how exactly those calls touch the outside world.

I don't like employing the phrase "separation of concerns" that often / without serious thought, but this is seems to be a valid use case for it. Presentation components shouldn't care about how fetches data, they should ideally just be a function of their props. Even container components should only care about what data they are accessing, not how it comes to be in the data store.

What you're asking for could just be a plain JS library - when you ask for certain routes in your app, fetch some data. When it comes in, handle all those edge cases you describe. Update the data store. When that happens, we're finally back in Redux land. It doesn't care about how you fetch your data, all it cares about is _that_ you touched it at all.


When I say comes with React, I mean like immutability-helpers or Redux or the concept of higher order components, or the idea of css modules. I think it would be a good, optional, companion.

(And the following is not directed against you, but a comment in general: I often feel that many people on HN never heard about the principle of charity, assume I don't know what I'm talking about, and when there are two ways to interpret what I say, assume the least sensible interpretation. This makes commenting quite stressful sometimes, and you feel like having to hedge every comment... Like I tried in the first sentence.)


I do think that there is some kind of implicit framework living within a smart combination React, Redux, and Immutable.js that combined with something like Uncle Bob's clean architecture could probably become a standard within the React world. My company is maybe 50% of the way there towards such a thing, and it really is a pleasure to work with.


This relates to the discussion I've been trying to have on potential abstraction layers that could be built on top of Redux to make it easier for some people to learn and work with [0]. There ARE a large number of existing libraries out there for things like fetching and managing normalized entities [1], as well as some more extensive frameworks like `dva` [2].

I'd be interested in hearing more details about what your company has put together. If you get a chance, please drop by the Reactiflux chat channels [3] and ping me.

[0] https://github.com/reactjs/redux/issues/2295

[1] https://github.com/markerikson/redux-ecosystem-links/blob/ma...

[2] https://github.com/dvajs/dva

[3] https://www.reactiflux.com


But React isn't a framework. It's only a view library. So by definition, it shouldn't care less about Ajax. Similarly, Redux is only a state-management container. It also shouldn't care about Ajax. What you're probably looking for is redux-saga[0]; it provides the tools to let you easily write all the fancy functionality you're talking about.

[0] https://redux-saga.js.org/


Relay is what is supposed to be doing this for React. I highly recommend Relay if you have a graphql api to talk to. I had to fight it initially (the docs are not good enough, although better than before, and I need to contribute what I learned) but once I got going it's made what took an incredible amount of time in Mobx, Redux, or Flummox much easier.


I have a network-state in every application, usually as a set of "NetworkRequests", which are data-object that describe a request. Just like I sync the UI-state to the browser using React, I sync the network-state to the network by

a) using a custom NetworkManager, that takes a set of requests and syncs it with currently running requests.

b) using react itself. In a simple project I created a ReactComponent for every network-request. The render() is just an invisible div, the actual requests get started and stopped in componentDidMount() and other life-cycle hooks.

This approach works everywhere, it is serialisable and easy to think about.

I tend to write the redux-part ("controller") of my applications myself, it's seldomly more than 100 lines and more adaptable to my needs.

And I never use immutable.js, it's really unnecessary and slows down development-speed (via it's weird api) and runtime-performance.


This sounds like a good use case for Promise.all() and fetch:

  const first = fetch(endpoint1);
  const rest = Promise.all([
    fetch(e2), fetch(e3), fetch(e4),
  ]);
  // cancel here
  const json1 = await first.json();
  const json234 = await rest.json();
While native promises can't cancel on their own, with a library like Bluebird you can get that functionality.


Yes! Promises and window.fetch are nice, that's what I based my code on. I am thinking about switching to axios (or Bluebird) to get cancellation, though.

But this is just the low-level code. Instead of (pseudocode):

    window.fetch('/the/api/url')
    .then(res => res.json())
    .then(json => this.setState({thing: json['thing']}));
I do (something like):

    fetchFromServerOrCache('param', 123)
    .then(obj => this.setState({data: data}));
The minor difference is that I do some processing (ok, you can do that somewhere is), but the main thing is the caching. The user can drag a slider bar and select different 'frames', and I don't want to transmit everything again if the frame was already selected. For various reasons I can't rely solely on the browser cache. One reason is that I prefetch all frames the server already computed at the beginning. So I want to check if the frame is available from the initial batch, or a subsequent fetch, and if not, fetch it in place. I wrap it into a promise so the calling code does not need to know about the caching.

I then pass the state to a child component which is as pure as possible.


Shouldn't the browser be doing the caching? Now that they even have the Fetch API, which can return actual JSON objects, they could even cache them pre-parsed.


That would be ideal. But my data takes a few hundred ms to be computed on the server per data point. So when I start up, the server sends all data it already computed before, compressed, in one request. Then the response for data point 123 is not in the browser cache for `/api/points/123`, but maybe it is in `/api/points/precalculated`.

My code then shouldn't care if the data came in the initial prefetch, or a later fetch, or is fetched in real-time, or even computed on the client. Just:

    let res = await fetchData('setting', 123);
    this.setState({property: res.property});
This is what I'm currently doing. I think there could be a library that helps you to write `fetchData`. Or maybe you'd have a special react container that you'd just wire up appropriately.


This is one thing I miss about Ember. We recently moved to React and I'm really starting to miss Ember Data (even though it can be very picky).


I haven't used Ember Data much. I'd be curious how you think it could apply or could be ported to React. Maybe you'd have time to write up a short gist of what you wish you could write in React?


Yes Ember-Data was great thing to have in Ember, something I miss from React ecosystem. In the early days was a bit unstable but now it's super stable and flexible (serializers/adapters customization etc). I think there should be an initiative to get it out of Ember so that you can use it with other projects as well.


I plan to use it in a React-Native app for a JSON/REST API.

Why not, isn't it standalone?


Shameless self-plug. I developed a design pattern I call "vacancy observers" that solves a subset of the Ajax problem. Basically, fetching data for display; AKA the "R" in CRUD. My POC implementation is on Github.

https://github.com/greim/motel


IMHO Redux is a heavy, clunky and awkward practice that is only holding React back.

My advice to anyone reading this forum is give MobX a try before deciding to commit to Redux.


Don't kid yourself, MobX comes with it's own baggage. Both are great libraries, both have advantages, both have drawbacks.


What are the downsides of MobX that you've come across? The main ones I've encountered are not being sure why something isn't reacting (always my fault but not always that easy to track down), odd interop issues with observables actually being "proxy" objects (e.g. useless console.log unless you call toJS), I guess no middleware-type concept or Saga type side effect management (never really used middleware in Redux and disliked all the ceremony around side effects)... that's all I can think of right now but curious to know others experiences.

I honestly can't imagine any reason I'd go back to Redux aside from if it was used on a project I was working on though. I can develop so much faster and with fewer bugs (as typechecking MobX code thoroughly is much easier than Redux with Typescript) that there's no comparison, and like the OP, I think everyone should try it out - you'll almost definitely be pleasantly surprised!


I've been working with it recently. The lack of prescriptiveness is an issue generally. No different from not having a library, but it's worth considering.

The library itself works really well. Use strict mode and everything is super fast and reliable.

Today we've been evaluating mobx-state-tree. It has some noise (not as bad as redux). It's opinionated which helps to remove architecture decisions. So far it looks promising.


I think this is why the MobX fanboyism irks me so much. It's a great little library but it does not solve the problems I have. I want to enforce the smart/dumb paradigm, I want to be able to quickly grok app state and monitor updates, I want nice dev tools, I want the data to be separated from components to the highest degree possible, I want to persist/restore complex app state. All of these are fundamental talking points for Redux and largely unnacounted for by MobX.

If all you switched to MobX just to avoid the boilerplate you didn't need Redux in the first place.


Well, the main reason for using these libraries is to automatically drive react. You want it to be easy to change your state and have that mirrored in the interface.

Mobx helps with much of what you've asked for above. Mobx-state-tree will give you even more from that list. Personally I think the persist/restore goal (and time travelling) is overrated (though mobx-state-tree will give you those).


It does not give you more from that list. MobX is, by design, non-prescriptive about who's touching your stores, how they're being passed around, how they're being updated, or how the API of your store looks. It's all fine if you have one or two developers but is a dangerous thing for large teams.

Have you used Redux's devtools? I wouldn't give those up for anything. Not sure if MobX has anything comparable.


I have used them, yeah. Mobx-state-tree (MST) can be wired directly to the redux dectools.

The strict mode in mobx ensures that stores can only be updated via actions, so you can restrict updates from that point of view.

On the flip side - mobx makes it dead easy to minimise your core state and transform it efficiently (and declaratively) for use in the front end (or wherever). I'm told reselect helps that use case now, but you'd be hard pressed to do a better job than mobx in that regard.

Personally, I found that my code was too obscure with redux. In implementing our login flow (it has more paths than most), I found that it was hard to see the real code between the architecture.

As ever, it's important to evaluate these tools critically to see where the fall down (which is what I've been doing with MST today). Too often people evangelise their product of choice while hiding the areas in which it's weak.

And to play devils advocate, redux will have you push a lot of code into middleware where people are left to do all sorts of crazy - it's not all the rosy enlightened path :-)

One of the things that pulled me to MST was that I couldn't see a simple way of managing cross-cutting concerns with my mobx architecture. MST (and redux) make that dead simple.


I don't see the need for either Redux or MobX. React is the V in MVC. Use an MVC framework with React, and everything get simple, easy and productive. There are MVC frameworks that work well with React. Redux is unnecessary complexity and the need for it came about because of ReactRouter. If you use an MVC router you can avoid a whole bunch of complexity.

BTW, using MVC doesn't imply two-way data binding.


People should learn eventEmitter or PubSub before learn redux


Why?


Redux is too complex and too many line of code. Most of activity why need redux are async fetch and eventEmitter notification. My advice is try eventEmitter first. If u need more, than jump to redux or mobx. The main reason use redux is if u need time travel


I don't understand why anyone would use React at all with the ridiculous license.


Well, there are many reasons to use React (the large ecosystem means you can find libraries and tutorials easily, for example) but yes, the license is a deal breaker for many, especially larger companies with legal teams who actually understand the ramifications.


It depends on how many software patents the company owns. In most cases it's 0


It could also matter if you're in violation of a patent held by Facebook or any of its subsidiaries.


Microsoft has no problem using React -- what are the ramifications?


Microsoft, Netflix, and Twitter most likely have agreements in place with Facebook regarding the use license.

Source: I worked for a large company that had banned the use of React for all external facing projects, recently Facebook and their lawyers came to an agreement and now it's widely used.


Doesn't Netflix as well?


Yep, and Palantir also. I wish my company would be more open to using it, but the patent issue makes it a non-starter for us.


If you're MS, there are no ramifications.


They recently changed the RocksDB licence (https://github.com/facebook/rocksdb/commit/3c327ac)

This reopenned the discussion about React licensing (https://github.com/facebook/react/issues/10191) so maybe this will change soon.


Not sure what specifically your aversion is to the React license, but a similar project - Preact - uses an MIT license: https://github.com/developit/preact

NOTE: not affiliated with Preact (I live in the caves of the backend).


How does Preact not violate React's patent if it's a drop in library?


React isn't patented


My bad it's a "patent rider". I should know better.


When has the ridiculous license ever been an actual problem for anyone?


What is wrong with its license?


They're referring to the 'patent retaliation clause', see: https://medium.com/@dwalsh.sdlr/react-facebook-and-the-revok...


Logically following the conversation.... What's wrong with their patent retaliation clause?

The link you provided basically says it only matters if you are a patent troll.


Yeah I don't have a stake/opinion, just posted that particular article because it's a recent, thorough take, by a lawyer.


My understanding of this licence is "we're making open-source software, play by the rules and don't sue us or we might find other ways to put you in trouble"


wow, downvoted for saying you don't understand something. Great job HN.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: