Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Redux Offline – Build Offline-First Apps for Web and React Native (github.com/jevakallio)
174 points by thekenwheeler on March 30, 2017 | hide | past | favorite | 41 comments



Neat example of the kinds of things that Redux helps make possible (or at least more feasible).

If anyone is interested in learning Redux, I keep a big list of links to high-quality tutorials and articles on React, Redux, and related topics, at https://github.com/markerikson/react-redux-links . Specifically intended to be a great starting point for anyone trying to learn the ecosystem, as well as a solid source of good info on more advanced topics.

I also maintain a catalog of Redux-related addons and utilities at https://github.com/markerikson/redux-ecosystem-links , which lists things like middleware, store persistence management, pre-built logic for managing collections of data, logging/linting devtools, and much more.


Slightly off topic, but how do people manage state that aren't using Redux? When you google "redux alternatives", you typically get results for different flavors or variants of redux. But are there other fundamentally different paradigms for managing state? I love Redux, but I'm really curious what else is out.

Also, the optimistic updates with rollbacks in this implementation is pretty neat.


I've been using Mobx very successfully on many of my projects now (both React & React Native). I'll prefer Mobx any day over Redux, just due to it's sheer simplicity and ease of use. Read: No need to burden your brain with the cognitive load of actions, reducers, dispatching actions, selectors etc.

Mobx v/s Redux does kick off the OOP v/s Functional debate, but as a developer my productivity and effectiveness is measured in terms of my ability to ship software not in terms of my programming style, and it's my personal belief that Mobx does make me more productive as compared to Redux.

For developers new to the whole Flux/Redux/Mobx/State Management world, I highly suggest to give Mobx a try.


Maintainer of Redux here.

I concur with giving Mobx a try. I'm using it at least one product so far and it's been working out great.

One thing I will say is that because your subscriptions are set up implicitly, it's easy to have things misbehave in unexpected ways. For instance, if you update multiple observable properties in a single function, it will fire off observers multiple times. That could put you into an unexpected state and cause some errors.

Luckily, almost every time I've run into this kind of issue, I've discovered there's an API to cover that case (runInAction in the previous example's case). And they APIs themselves are really neat and fun to work with. `when` and `observable.array`'s extensions are some of my favorites.


Do you pass the MobX stores down to every child component as props or do you use @inject? I started with the former but all of a sudden all my components had all these "default" props that cluttered things up. @inject seems great but the documentation doesn't push it enough to make me believe it's best practice.


Neither. Just import a singleton root store and reference it directly.


I was using global stores but recently moved to @inject. I needed a way to reset my stores on logout. Hence now i create a root store and initialize rest of the stores.


Can you suggest a good MobX guide/tutorial to follow or a place that keeps MobX resources such as acemarke redux lists?


You might not need Redux, written by the author of Redux: https://medium.com/@dan_abramov/you-might-not-need-redux-be4...


MobX is quite popular, and I wouldn't call it a variant of redux.

Also, just storing state in your higher level components can work for much more complicated apps than many think.


I've done the latter and even though it's possible, it gets tedious/unproductive pretty quickly.

To elaborate: in 'response' to the webdev tendency I have to use the latest and greatest, and the HN articles about this phenomenon, I've done a few React projects with a conservative mindset.

React-router I don't miss too much for much of it. I could also do without a bunch of ES6/7 features, TypeScript, and so on. But with each of these projects I wish I'd used Redux, MobX, Baobab, and so on instead of the 'vanilla' approach of keeping state in my higher level components.

tl;dr: if you're gonna be conservative, leave state management as the last thing you 'conserve' on.


This is so true. Just apply the Redux idea of smart/dumb components but without actually using Redux. Higher level component(s) becomes smart and handles the state changes while passing down only properties to children.

Usually I start an app like this and when things get really complicated I add Redux and refactor the state management out of my top component.

MobX looks interesting, however didn't get to try it out yet, only briefly looked over it. I find it a bit annoying that they introduce even more syntax overloading - annotations - as if ES6/7/JSX is not enough already. Will give it a try on a pet project soon.


To be fair they give many examples of using mobx without decorators. I use them because they're baked into typescript, but I wouldn't use the Babel plugin, it seems less mature.


It's also quite easy to roll your own solution. I used to do this before I heard about Redux, and the whole library was ~100 lines I think (not including tests). My implementation exposed a store and allowed you to subscribe to "events" on it (postAdded, etc). It ended up working similarly to Redux, but without the reducers (you would just handle the event in-place).

That said, these days I would never use anything but Redux. MobX is gaining traction as a viable alternative, but I just love having all possible mutations spelled out explicitly.


I've been using baobab[1] which is:

> a JavaScript persistent and immutable (at least by default) data tree supporting cursors and enabling developers to easily navigate and monitor nested data through events.

It's a fairly simple library to read and understand and it's well written. I have a couple decent sized SPAs working on top of it, and I store the full data tree using localForage for offline use.

1: https://github.com/Yomguithereal/baobab


I've had good experiences with Baobab. The main reason I lean toward Redux is that I want my clients' product to be as 'standardized' as possible. While this is difficult in the JS world, React and Redux fit the bill (or are close to it).


I also like Baobab. Way easier to debug when things go wrong and it works very reliably so you very rarely need to do that.


I have no experience with either (I write library code, not app code) but I see MobX mentioned here frequently.

Here is a comparison.

https://www.robinwieruch.de/redux-mobx-confusion/


Not a strict replacement, but I am really enjoying Elm.

The architecture is very similar - I think it was the inspiration behind Redux. You get to use a more succinct syntax and there is a compiler underneath it that supports the whole process. I have only recently started with it, bit I am finding the adage that 'if it compiles it will work' is proving remarkably accurate.


I just came across Vue.js the other day, while exploring options for quickly banging out small tools. Getting tired of the clutter in a full-featured React project.

It offers more than one strategy for managing state; there is simple two way binding between a JS object and the DOM, there is the Elm-inspired vuex, and also it can integrate with Redux. http://vuejs.org/v2/guide/state-management.html


Flux is a standard idea in the React world... I don't know that there are any "fundamentally different paradigms" for managing state in React.

Before Redux came out, I built my own state management system around Backbone. I recommend using Redux.


I'm doing well with storing state in multiple nested components, each state in the component it "belongs" to.

This approach matches well with GraphQL (without Relay -- but with Relay I imagine it would fit even better).


Since we have been using graphql and apollo-client i personally havent had a moment where we really missed redux[1]

[1]: technically apollo client uses redux internally but they keep it nicely wrapped for you


A huge, global, shared state makes it much harder to have an arbitrary number of a component, compared to each instance of the component holding its own state.

It's also a lot of boilerplate when you just want to add a simple toggle to some component.


its better to search for "flux alternatives" since flux was the earliest react state management library


Use Mobx if you're one of these people who like doing less work and writing less code to achieve the same end result as Redux.


This looks pretty solid, and the ability to create our own resolvers makes things much more flexible.

Currently creating a cross-platform react native app using realm.io for persistence. While it's is great, the debugging performance is slow (rerouted RPC calls) and it has a few quirks (each model is a proxy, odd optional field support, poor error messages when data is erroneous).

The benefits of this seem to be:

1. Pre-created retry logic, optimistic update logic

2. Less effort to save data to realm

3. Less effort to load data from realm on app reloads

4. Potentially shared actions across our apps/web projects, as there's no realm specific abstraction in our apps.

Gonna have a look at implementing this one day soon to compare and learn :)


Please note: This is certainly a very helpful library, but it's made to work with some kind of server/API. The defaults assume you get a connection again within one hour. Obviously, you can tweak the defaults.

But if you want to build an app with its own real functionality that has sync added (like a TODO list that syncs with other devices) and is entirely offline-first where you can go weeks without a connection, you better keep searching. Maybe have a look at PouchDB.


Other than Couch/Pouch, are there any other projects providing solutions to this problem? The one thing I dislike about couchdb is the default "user-per-db" model.

I'm interested in solutions that allow a traditional relational db instead of a key-value store. Seems like with indexeddb on the client, and postgres on the server, you could probably keep a segment synced.


I haven't found one and I really wonder if everybody rolls their own sync solution.

> The one thing I dislike about couchdb is the default "user-per-db" model.

Why exactly? I think the overhead of the DBs is rather small. It's not like having a MySQL DB for every user ;)

Also, you can achieve something like "global data" as well: Either replicate from users' DBs to a shared DB or maybe make some kind of "system" user that has access to the users' DBs. I'm not an expert, but that's what I figured out so far with my limited experience.


Performance-wise, i think it's probably fine. But it doesn't play well with any kind of group permissions. Things are either owned by a user or they are almost impossible to sync.

Let's say you are making a CRM with couch/pouch. Let's say that you have permissions to see a Customer record, but it is shared across your company. How do you sync that? It's not owned by a user, it's owned by the company. What happens if permissions change?


Realm is awesome for this. It is not a relational database in the traditional (SQL) sense, but more of an object database that allows for relations between the objects. Their sync backend is pretty neat.


Realm has no real support for web apps. It's for native platforms only. Dealbraker for me.


Also not relational, but Meteor (MongoDB) with GroundDB for the client provides optimistic UI, offline persistence, and sync on reconnect. Unlike Couch / Puch, you can easily share a DB between users with authentication / authorization. Synced content can be controlled with subscriptions.


Hi! I'm the author of the library, and just wanted to say that you are absolutely correct about Redux Offline not being a suitable solution for weeks of active offline use :)

Regarding the "get a connection within one hour", that's only for automated, scheduled retries. When your app becomes online or is started up, no matter after how many hours or days have elapsed, we do continue retrying the messages unless you have a discard policy in place to remove them. The limited retry policy is related to not banging on a backend that is down or unreachable, etc.


I'm re-learning Redux now, does anyone else think that it might be overkill for an app that doesn't require any user input?


Quite possibly, and it's always a good exercise (and in this case justifiable) to do it the 'vanilla way'.

That said, even for relatively simple, non-input type projects I've found that Redux is worth it. I got thoroughly sick of passing props down multiple levels.

Furthermore, I found that I often ended up making mistakes where my components were too reliant on their context (even when considering variable/prop naming). Redux, I feel, extends the 'pit of success' effect that React has; when I use it I'm more likely to properly isolate components.


My suggestion is to not use until you need it, at which point it's easy to add. I find that most apps that I write benefit from it, but there's no point in using it if your use case doesn't need it.


Yes. Redux's advantages are only relevant if you have a lot of changing/updating data, which usually comes from user input. My personal litmus test is if the Redux devtools (https://github.com/gaearon/redux-devtools) sound like a must-have feature.


We're building a project management tool over at Braid [0] and it made a lot of sense for us. It saved us a lot of nasty prop-passing business.

What does your app do?

[0] - http://braidhq.com/


If all your data is read-only, then yes, Redux is probably overkill. You'd be fine just passing the data down as props from a higher-level component.




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: