
Show HN: Simple way to share state using React Hooks and Context - hazdiego
https://github.com/diegohaz/constate
======
aogaili
Well, that's nice. I guess the React community is aiming to try every
permutation within potential state management solution space, I mean something
have to work after all.

~~~
sametmax
I remember when you had to choose between flux, redux, alt, reflux, flummox,
fluxible, fluxxor, marty.js, fynx, MacFly, DeLorean.js, fluxify, fluxury,
exim, fluxtore, Redx, fluxx... (no I'm not making those names up:
[https://github.com/kriasoft/react-starter-
kit/issues/22](https://github.com/kriasoft/react-starter-kit/issues/22))

Every single time somethings come up, in the JS word, they try to repeat one
of the mistakes from the past and completly ignore everyone else solutions and
experience. It's like a compulsion.

In a year or two, your dependancies will be a representative sample of all
permutations of those solutions, and will have to be maintained in that state
forever, incompatible, or abandonned. You'll open some of them, trying to fix
it, but you'll notice they all use different coding style, best practices,
libs, and tooling. The dev that fought you in comments saying it would be fine
is nowhere to be found now.

Most JS devs don't care. They don't maintain their stuff. Appart from the
stuff that get famous because made by great coders (no matter the language),
most projects die silently. There is a terrible graveyard hidden behind the
corporate wall. Java, C++, Python and even Ruby projects are standing well and
alive, next to the countless bodies of the last generation of JS frankeinstein
monsters that were hype-sold to upper management to create something that
could have been done in PHP 3.

Then a new stuff will arrive in the JS space, with again the potential of
creating more confusion, more technical debt. You will raise your voice, and
the JS community will scream back at you that you don't know what's good, you
want to live with cavemen, and everything is great. They will get angry, and
never see any problem.

Then rince and repeat.

~~~
nicoburns
That, or you can continue to use redux, which has existed since 2015, is
mature, and still by far the most widely used state management system for
react.

~~~
black-alert
Redux, made for very large scale applications. Most companies shouldn't use
redux at all, just as Dan Abramov said several times that you probably don't
need it.

For unknown reasons most front-end developers don't wanna hear that and love
to start with mega complexity and boilerplate where just a simple flux store
or a library like 'unstated' would suffice. Anything leaner than redux is very
welcome for the average companies web app imao.

~~~
sametmax
> Redux, made for very large scale applications. Most companies shouldn't use
> redux at all, just as Dan Abramov said several times that you probably don't
> need it.

As per my own comments, I agree strongly.

> For unknown reasons most front-end developers don't wanna hear that and love
> to start with mega complexity and boilerplate where just a simple flux store
> or a library like 'unstated' would suffice.

Not unknown, no. Because FB promoted Flux like it was something magical and
never seen before, talked about store without providing best practices or
reference implementations, and so many store implementations came out at the
same time. And most tutorials, not knowing exactly what to recommand to
provide some state to your tiny app, started all to promote one store or
another. So people though it was mandatory.

It's like with react tutorials.

When I teach react, I make sure people start by just dropping a script tag,
and use createElement. No JSX. No webpack. Most of the page is even static
HTML.

Only once they got the basics covered, I build on that up to abstractions,
tooling, best practices, etc.

That's not what you read online. Online, people drop some magic lines and say
"see how this todo list example is easy ?", then let you die here.

~~~
nicoburns
I agree with you in terms of learning React. Not sure I agree in terms of app
size. Yes, there's some boilerplate associated with Redux. But it's pretty
simple, and I find the "one way data flow" model really does simplify thinking
about how state transitions work, in a way that is beneficial even for small
apps.

------
Jacqued
Hey Diego!

Nice idea and examples! Let me know if I'm wrong, but the main difference
between `createContainer` and a `React.createContext` call is that you memoize
inputs, correct?

The way this interacts with Hooks to enable state sharing is pretty cool.
Hopefully someone builds a complete i18n lib on top of something like this.

------
jsnelgro
Also check out react-atom: [https://github.com/derrickbeining/react-
atom](https://github.com/derrickbeining/react-atom)

I stumbled across it earlier this week and it's a joy to use so far. The api
is inspired by clojure atoms, and typescript inference works great out of the
box.

~~~
bokchoi
Thank you, this looks really interesting. I've enjoyed using reagent and re-
frame on personal projects but ClojureScript was too much for my team to
swallow.

------
ng12
Honestly I think I'm done with state management libraries. There's no longer
anything I can't write cleanly with React.Context and hooks. The overhead of
adding an dependency is no longer worth it.

~~~
RobertKerans
That's great for simple stuff, but without implementing some extremely hairy
bitmasking logic via the callback to createContext, if you have any kind of
complex state, how do you prevent rerenders of vast chunks of the UI, and the
performance hits that causes? Context is really nice, and works fantastically
for simple stuff where it's fine to just redraw the world (authorization or
theming for example), but it's not a replacement at this time

~~~
tiuPapa
How does using a state management library prevent rerender of vast chunks of
UI? Isn't that the responsibility of the react's reconciliation algorithm? Is
there any way of fine-tuning the rendering, purely from a state-management
perspective (I know about Pure Components and shouldComponentUpdate lifecycle
hooks)? I am genuinely curious.

~~~
acemarke
In the case of React-Redux, we do a _lot_ of work to check the derived values
you've extracted from the Redux store, and prevent your own component from re-
rendering unless those values have changed.

See my post "The History and Implementation of React-Redux" for more details:

[https://blog.isquaredsoftware.com/2018/11/react-redux-
histor...](https://blog.isquaredsoftware.com/2018/11/react-redux-history-
implementation/)

~~~
sorahn
Somehow the codebase I recently took over has managed to mess this up. Every
time any part of the state tree anywhere changes, the whole app re-renders.

I’m trying to track down why this is an issue, but so far I haven’t had much
luck. Do you know of any tools that can assist with this specific kind of
debugging?

------
rtpg
Is there a way to use the React hook stuff without having to put the backend
logic _inside_ of your UI generation code?

It really feels like if there was some way to put this really dirt-simple
counter code into a plain-Jane Javascript object then a lot of this hand-
wringing about state management in React goes away (contexts are an
interesting little solution to things though)

~~~
gedy
Sounds like you are looking for something like MobX?
[http://mobx.js.org](http://mobx.js.org)

~~~
crooked-v
There's also Redux, which is harder to wrap your head around starting out, but
has great edge case debugging capabilities (you can "time travel" forward and
back with changes) and really efficient-and-seamless cached derived data with
selectors.

~~~
fastball
Rematch[1] makes it really easy to get started with Redux.

1: [https://github.com/rematch/rematch](https://github.com/rematch/rematch)

------
thecatspaw
I dont get hooks. How is this simpler than something like this?

[https://jsfiddle.net/xv7y9eoz/](https://jsfiddle.net/xv7y9eoz/)

~~~
wawhal
I don't buy the way things are done in this library (constate). I wouldn't
import a library just for doing this. It is not very hard to achieve the same
with plain `useContext` and `useState` directly.

That being said, I don't agree that hooks are futile, because, using hooks,
your state logic can be reused. For example, if your app uses 10 independent
counters (with different render logic and different styling), hooks are
definitely useful to reuse the state logic.

------
rbalicki
Seems to solve a similar issue as
[https://github.com/jamiebuilds/unstated](https://github.com/jamiebuilds/unstated)

~~~
ricardobeat
Both solve state management issues, but really different goals.

Unstated has state containers as separate entities. This one is about
seamlessly switching from a local useState hook to a context-based one with
minimal code changes.

I’m not convinced it’s worth the hassle vs just creating your own contexts
though. Here is the full source:
[https://github.com/diegohaz/constate/blob/master/src/index.t...](https://github.com/diegohaz/constate/blob/master/src/index.tsx)

~~~
rckclmbr
> I’m not convinced it’s worth the hassle vs just creating your own contexts
> though

This is what I was thinking when running through the source. The problem to
solve, I think, is to get rid of the providers. Or rather, make it less jsxy.
For application-level contexts, you can easily have 10+ providers at the root
of the application. You could make them HOCs, but that's still super ugly.
Hooks made the consumer side a lot cleaner, now it's time to do something
about the provider.

------
BilalBudhani
I guess I'm still in a minority who likes Redux.

~~~
HyperMassive
Nope. plenty do. I do. granted its verbose, but it gets the job done nicely.
easy to follow, plain functions all the way down.

~~~
molszanski
And what about those `reselect` wires? And that `connect` and `mapStoP /
mapDtoP` stuff? Doesn't that "bother" you? Or you just mentally "pack" it into
the verbosity basket and ignore it?

~~~
WorldMaker
`reselect` is an option that you don't have to use.

The mapStoP and mapDtoP are just plain functions that do what they say on the
tin. Easy to read/write once you understand the pattern.

The connect HOC like all HOCs is a bit of a smell, but easy enough to use
without understanding much about HOCs.

Likely soon hook replacements for connect will make all that "verbosity" even
simpler and easier to work with.

For instance, useMapState and useActionCreators from this proposal for redux
hooks: [https://github.com/epeli/redux-hooks](https://github.com/epeli/redux-
hooks)

~~~
molszanski
> `reselect` is an option that you don't have to use.

Of course.

It just happens that for my real life needs I've needed state that was derived
from redux state: filtering, selections, pagination, normalizing /
denormalizing state, relations between entities (classic library data model
problem) etc.

So I kinda can't "imagine" any "serious" work with redux without helpers like
reselect etc.

> Easy to read/write once you understand the pattern.

Sure, there is nothing "complex" about any of that.

And I am genuinely asking how people deal with that.

It is just way too verbose for me. So I am wondering, how other people
approach it.

Close their eyes and plow through? Don't really care?

------
austincheney
Maintaining state is an easily solved problem severely over engineered by
frameworks. The central issue why this becomes so complicated is because
developers who aren't comfortable writing original code would rather deal with
an ocean of configurations than a few architectural decisions.

That is problematic because configurations are settings not decisions, which
means you need work arounds for edge cases and work arounds for the work
arounds. If instead you treat everything as a requirement instead of anything
as an edge case then you are forced to make decisions and write the
corresponding code. New requirements may necessitate refactoring of current
decisions down the road, but the code stays clean, small, and deliberate.

At the most simple you only need three things: a central consolidated point of
settings (object), storage (localStorage), and interactions isolated to their
respective purpose (handlers).

~~~
IceDane
This is such a gross oversimplification of the problem I can't help but doubt
you've ever actually written a complicated frontend application using today's
modern frameworks.

I have explored this space from nearly every angle. I've tried a multitude of
languages and technologies, and there is no place where this has been solved
completely and there are always drawbacks to any solution. But that doesn't
mean those solutions just exist because their authors were bored. They exist
because they actually solve a problem.

I would very much like to see you write a large react application using only
the concepts you mentioned. How are you going to deal with side effects? You
realize you can't just fire those off willy nilly, right? How are you going to
pass information upwards or across the component hierarchy? Callbacks? Have
fun with writing that and reasoning about it afterwards.

People love to bash on the JavaScript ecosystem and rarely do I see anyone
praising it as it deserves. There are some incredibly ingenious solutions and
architectures that have been invented in that space, and anyone who isn't just
a troll trying to fit in with the other cool kids and has actually tried to
write a complicated frontend application today appreciates the hard work that
is happening there, and understands why new solutions keep being invented.

~~~
austincheney
tldr; everything is too hard

I have been writing code for more than 20 years and writing JavaScript for
more than 11 years full time. The UI, accessibility included, is not the
challenge. I have been doing this long enough at enough employers to watch
people fail the same ways over and over and consistently qualify bad decisions
with the same repeated excuses.

> This is such a gross oversimplification of the problem

It is not an oversimplification if proven in practice more than once.

> rarely do I see anyone praising it as it deserves

I love JavaScript/TypeScript. Some of the complaints against JS are absolutely
justified and some aren't. The unjustified complaints are typically from
insecure developers of other languages that loathe the completely foreign
expressiveness and flexibility allowed by JS. The mountains of code some
developers require to perform trivial tasks is absolutely worthy of ridicule
though.

------
modarts
How many times does the React community plan on skinning the same cat?

~~~
Tarks
It's a mean cat. In the last few years I've ended up going through cycles of
doing a react project, moving on for some months then another react project.
Each time I've come back I've been impressed with the changes and they've
often improved parts of react I'd previously found wanting.

