
A SoundCloud client in React and Redux - rwieruch
http://www.robinwieruch.de/the-soundcloud-client-in-react-redux/
======
fpgaminer
There seems to be a big blind spot in these Real World React+Redux tutorials
when it comes to forms.

For example, say I have a page with reviews on it. So there's a Component that
handles editing a review. Where does the state for all the form inputs go?
Does it go in the Redux store? If it does, then every time the user types a
letter you get an event, which goes walking backward through the component
tree until it hits the review editor Controller, which generates an action,
which dispatches to the store, which gets reduced causing a state change,
which then percolates back up through the Controller/Component tree to finally
add that letter to the input. That walking back and forth is bad enough on its
own, let alone generating an entirely new state (because the state is
immutable) for every single letter the user types. It's inefficient, and it
adds noise into the action log.

The alternatives seem to be storing the state in the component in which the
typing is happening, or in the parent Controller, and then only generating
update actions against the store when some "finished typing" event occurs
(i.e. onBlur or timeout). Of course this seems to go against the idealistic
implementation of Redux where all the state is stored in that one state object
and it's immutable.

My point being, I haven't stumble across a "real world" tutorial that goes
over this stuff. I wouldn't quibble about that normally, as I'm happy to play
around and find the solution on my own, but this feels like such a common and
important task (what website doesn't have forms of some kind?) and the
performance and maintenance implications of how this is implemented seem
large. So it would be nice if there was a "We built this huge web app using
React and Redux, this is how we ended up doing forms and it works well for us"
article.

~~~
Renner1
I agree with your point and disagree with redux-form being a valid solution.
redux-form creates a very restricted and crippled API for getting form data
into a redux state object and does so at the expense of the spirit of React's
componentized model. Any redux-form state needs to be isolated under a special
root object specifically for forms. You can't just mount some existing part of
your state object into a form because of this. Not to mention redux-form
properties have a whole bunch of other "glue" properties in addition to the
actual value of the form.

I question whether people use it in large scale production. This is one of the
huge downfalls of redux. It makes some things easier, but it makes the most
fundamental stuff (editing form fields) extremely contrived. This is the main
reason I don't see react+redux as a true answer to the challenges of SPA
development but a very rough, intermediate step which needs to be re-thought
while putting into consideration the most common use cases.

~~~
girvo
> _I question whether people use it in large scale production._

We tried to, and removed it within 4 weeks of development with it, for all of
the reasons you mentioned. It conceptually doesn't map to our Redux model, and
new developers struggled with it because of that. I ended up writing my own
"wrapper" to do something similar, but to be honest for most of our form state
it is handled within the components themselves (via this.state and friends)
and only sent to Redux once validated. React's built-in state handling is
still useful, specifically for these sorts of things.

~~~
davidjnelson
What are the pros/cons of setstate vs a batched state subtree for each
component and an aggregate state subtree for each component that matched each
form parent, specified by a string to a higher order component for the parent
form and a string for each component used to model html5 form inputs?

~~~
acemarke
Ah... you lost me on that statement. Can you give me an example of what you're
picturing?

------
iLoch
Having worked with Redux on a few different projects I'd probably recommend a
different approach than the one outlined in this tutorial.

One of the great things about React is the advice that you can put more in a
single file than you used to be able to. We seem to have forgotten that
concept when it comes to the data layer of most Redux applications I see.

I would suggest that people check out the Ducks pattern:
[https://github.com/erikras/ducks-modular-
redux](https://github.com/erikras/ducks-modular-redux)

To sum it up: your constants, action creators, action handlers, and reducer
all go in a single file. You can export anything you need from a duck file,
and the default export for any duck must be the reducer. This ends up being
really nice - no more rapidly switching back and forth between action creator
files, reducer files, your constant files, etc. It also allows you to easily
collect all your ducks and attach them to a redux store (thanks to the default
export.)

Some suggest putting any data fetching in the ducks as well - I think this can
be handled on a case-by-case basis - I tend to prefer to keep my data managers
in a separate "services" folder though, which are just files that export async
functions like "fetchUser(id)" or "fetchArticles()"

Ultimately there are many different valid ways to structure your code, this is
just one way that I've found to be much more enjoyable.

------
jorde
While Redux is much better than early Flux implementations, I feel that both
have the same issues: quite a lot of boilerplate, scattered logic and
confusion around best practices. Don't get me wrong, I really like Redux but I
feel that most of the time I'm writing either boilerplate code or trying to
decide how to structure my actions and reducers. Also combining
actions/reducers with components isn't particularly easy given that you still
need to combine reducers into one state. Not to talk about cherry picking
parts of state into props and then working with reselect to cache values or
normalize API responses...

Oh sorry, I think I had something that I needed to let out :)

Anyway, recently I discovered MobX[1] which, aside from the bad name, is
amazing. It's pretty flexible and has very small API surface but compared to
Redux it just gets out of the way. Granted, there's a lot of hidden logic
which feels like magic but in the end it allows me to build apps way faster
while still producing performant code. I have moved few projects from Redux to
Mobx and it's mainly removing code and files and bundling mobx stores with
components. At work I been able to explain it to coworkers in two minutes
where as it has taken hours or days for people to understand Redux. I highly
recommend checking out the React+MobX tutorial[2] and give it a go even though
it's not the hot thing of the week just yet :)

[1] [https://mobxjs.github.io/mobx/](https://mobxjs.github.io/mobx/) [2]
[https://mobxjs.github.io/mobx/getting-
started.html](https://mobxjs.github.io/mobx/getting-started.html)

~~~
tracker1
Don't map your reducers/actions to the components... map them to the
data/features they are tied to. If you organize by feature, you don't really
have to have your actions/dispatchers sitting with your components, but you
can where it makes sense.

~~~
tracker1
Just to expand... as an example...

    
    
        .../features/users/login
    

may contain both the ui components as well as specific actions/reducers
related to login... though other components may call actions under
features/user as necessary, because they correlate to the
data/features/functionality around users, where the components themselves may
be for other features.

I feel that once you stop trying to segregate by either component or type of
module/script that it tends to be far easier for someone new to come up to
speed in a project. It is taking practice and some thought, but has worked
very well where I've implemented this approach so far.

------
CognitiveLens
Cool to see so much packed into one place. In my experience with React and
Redux, there have been two major challenges in finding well-documented
examples to follow. First is finding anything that describes more than a toy
project that just demonstrates the most straightforward implementation of one-
way data flow. This tutorial isn't bad, although it's comparable to the
reddit-based tutorial in the Redux docs. The second challenge is finding
documentation that is up-to-date with the latest versions of all the tools.
This is even more challenging when the dependency versions aren't explicit -
it would be very helpful to add this info up front in this tutorial,
especially since Webpack 2 is just around the corner, and React Hot Loader 1
is deprecated in favor of the soon-to-be-release version 3 - dependencies in
the Redux-React world are moving fast so all documentation needs to be
'pinned' to explicit versions.

It's also good to see a pretty complete description of the testing setup,
although I have some concerns about the "inject everything into the `global`
object in setup" approach, which is a relatively coarse technique for
simulating a browser environment in Node, and means the unit tests are running
in a "special" environment unlike the actual running application environment.
No one has completely solved this problem, but it's an important part of the
discussion for anyone wanting to do things "right" from the beginning.
Injecting `React` as a global variable for convenience also makes me cringe a
little bit, given the ease of writing explicit dependencies in modern
javascript.

Nice step-by-step article though - I like that there are a growing number of
accessible entry points like this and I look forward to the community growing
and maturing to define best practices.

~~~
acemarke
That's one of the reasons why I've been pulling together a list of full-blown
open source Redux-based apps and larger-scale examples over at
[https://github.com/markerikson/redux-ecosystem-
links/blob/ma...](https://github.com/markerikson/redux-ecosystem-
links/blob/master/apps-and-examples.md). Mozilla Firefox's debugger (current
and future), the Wordpress Admin Panel, and the Jenkins UI all qualify as
reasonably more than a Todo List or Reddit Viewer example.

------
acemarke
Solid article. In addition, I keep a list of high-quality React and Redux
tutorials over at [https://github.com/markerikson/react-redux-
links](https://github.com/markerikson/react-redux-links) (as well as a Redux
addons catalog at [https://github.com/markerikson/redux-ecosystem-
links](https://github.com/markerikson/redux-ecosystem-links)). Working on an
update to the tutorials list today, and this article's going in.

------
tzaman
Nice tut, although I've learned one thing during past couple of months of
developing with Redux: middleware is very useful and often quite an
overlooked/underused part of the stack.

In this tutorial, the author makes the call directly in an action, which is
not its responsibility. Here's an example of the "api" middleware we've
developed
([https://gist.github.com/tomazzaman/a98f5ad3f052592e564862e4d...](https://gist.github.com/tomazzaman/a98f5ad3f052592e564862e4d508c844)),
and the beautiful part is, this is the only file in which async calls are
made. And it's a rather small file, which allows me to change to any ajax
library (like the native fetch when it gets more support) I want at any time,
with very little development.

Bottom line: middleware is awesome, give it a try. :)

~~~
acemarke
Doing API calls inside async action creators / thunks _is_ entirely valid - in
the end, it's still "creating actions". Just a question of how much
duplication you want to deal with, consolidation, etc.

But yeah, middleware is a concept that isn't talked about as much, but on the
flip side, there's dozens and dozens of middlewares people have created. In
fact, there's at least a couple dozen middlewares I've seen _just_ for doing
AJAX calls. See my list at [https://github.com/markerikson/redux-ecosystem-
links/blob/ma...](https://github.com/markerikson/redux-ecosystem-
links/blob/master/middleware.md) .

~~~
davidjnelson
And thunks for async get even sweeter with async/await/await*!

------
CraigJPerry
I look in src/ but nothing says SoundCloud client to me. I recognise the
structure of this app as following current conventions but the logic is
scattered by concerns I don't care about - e.g. I don't need a package called
constants, I know what a constant looks like.

Concerns I do care about are hidden from me across files and package folders.

------
icpmacdo
The past few days I have really been getting into the 3REE stack: React, Redux
and RethinkDB and have been learning so much. Here's a blog[1] outlining it
and a github example of it [2]. It has been great so far, what are some UI
libraries that I should take a look at, so far this looks like the best
option[3]

[1] [http://blog.workshape.io/the-3ree-stack-react-redux-
rethinkd...](http://blog.workshape.io/the-3ree-stack-react-redux-rethinkdb-
express-js/)

[2] [https://github.com/GordyD/3ree](https://github.com/GordyD/3ree)

[3] [http://www.material-ui.com/#/](http://www.material-ui.com/#/)

~~~
acemarke
In my own app, I'm using Semantic-UI as the styling baseline, especially for
inputs. There's a number of React wrappers around Semantic-UI, such as
[https://github.com/hallister/semantic-
react](https://github.com/hallister/semantic-react) and
[https://github.com/TechnologyAdvice/stardust](https://github.com/TechnologyAdvice/stardust),
but most of them create React wrappers around Semantic's jQuery-based widgets.
I'm trying to avoid use of jQuery entirely, so I opted for
[https://github.com/shinzui/react-semantic-ui-
kit](https://github.com/shinzui/react-semantic-ui-kit) instead. Not as
complete as the other libs, but a great focus on just wrapping the
CSS/className aspects of Semantic-UI.

Beyond that, [https://github.com/jquense/react-
widgets](https://github.com/jquense/react-widgets) is a great set of more
specialized input widgets (dropdowns, datetime picker, numeric spinner, etc),
and [https://github.com/rofrischmann/react-layout-
components](https://github.com/rofrischmann/react-layout-components) is a good
React wrapper around Flexbox usage.

------
babbeloski
At work I've started keeping the reducer in the actions file, anyone else do
that? This way they can share the same const declarations, and you don't have
to toggle between two files when most actions / reducers are pretty small.

~~~
kumaraman
I originally tried this but then discovered combineReducers() this will allow
you to organise your reducers into a single import. I found it a more sane way
to organise all of my reducers, as the majority of them were small. Here's a
link for API
[http://redux.js.org/docs/api/combineReducers.html](http://redux.js.org/docs/api/combineReducers.html)

~~~
jamra
That would combine your reducers into one. I believe he was referring to
putting action creators in the same file as their associated reducers.

------
flexd
Here is another example of the exact same: a SoundCloud client written in
React+Redux [https://github.com/andrewngu/sound-
redux](https://github.com/andrewngu/sound-redux)
[http://soundredux.io](http://soundredux.io)

------
ErikAugust
Huger: [http://cabin.getstream.io/](http://cabin.getstream.io/)

------
terda12
Looks very promising, thanks!

