7. WHAT ARE YOU (PROBABLY) GOING TO
NEED?
Webpack
Babel + presets
React-redux
Redux-thunk
Redux-logger
Axios or fetch-polyfill
Immutable.js
React
Redux
Jest or Mocha + JSDOM or Karma + Phantomjs
React-router
React-router-redux
What we actually
care about
8. WHAT ARE YOU (PROBABLY) GOING TO
NEED?
Webpack
Babel + presets
React-redux
Redux-thunk
Redux-logger
Axios or fetch-polyfill
Immutable.js
React
Redux
Jest or Mocha + JSDOM or Karma + Phantomjs
React-router
React-router-redux
What we actually
care about
25. WHAT’S ANNOYING?
Component testing connected components is hard.
I rely (mostly) on functional testing
Export both a connect()-ed and non-connected component
See: Erik Ras’ “ducks”
26. WHAT’S ANNOYING?
It’s difficult to call a method on a component wrapped as a high-order
component…
27. DON’T DO IT
BUT: you probably shouldn’t be doing that anyway:
pass data via callbacks passed from parent component.
Or pass data via a redux action
28. LET’S RECAP
Use ImmutableJS records for domain types in stores
Use ImmutableJS Maps often for store data containers
Use redux-thunk to make remote requests in actions
Async action creators should always return a promise
Reducer cases are not always 1-to-1 with actions
Let me know if you’ve figured out the component testing issue with
connected components…
HoC component wrapping cause some pain
Webpack is really the most annoying part
30. DEBOUNCE EXPENSIVE ACTIONS
Some independent top-level components say what data they want to
fetch from `componentWillMount()`
Debounce a single remote request
34. DECIDE WHAT WORKS FOR YOU
Frameworks are less about prescribing “the
right way” and more about getting everyone
to do things the same way.
- @thom_nic
38. I DON’T NEED ANGULAR-RESOURCE
This is actually (really) boilerplate. Replaced with this:
39. WHY I DON’T NEED ANGULAR-
RESOURCE
… and http thunks of thunks:
40. A WORD TO THE WISE…
Avoid temptation to do client-side data manipulation to attempt to
mirror server state.
Better to always fetch from the server as the source of truth
Notes de l'éditeur
What I’m going to present seems to be working OK for me.
It might not work for you. Try it yourself and decide.
• How many people have written a simple redux app?
• How many people have read some tutorials?
So you’ve heard redux is pretty rad. Lots of people say it’s cool. Maybe you’ve used Angular or Ember or Backbone and Marionette.
Well, react is like that, except….
Also react-router and redux-simple-router.
Also hot module reloading.
And the source maps. Never forget the source maps. You might spend a week getting those two things working.
So before you've started writing any code your package.json is going to look something like this!
Let's backup for a second. What you *really* care about is actually a small number of packages.
These are actually *really* simple to learn.
You’ll spend 4 hours learning this, and two weeks getting the tooling to work.
By the end, you’ll feel like this.
So what I'm really saying is, copy someone else's boilerplate example.
Let’s try to remember what we’re trying to achieve
You might have seen this before.
https://facebook.github.io/flux/docs/overview.html
Gross oversimplification of redux.
Or is it?
The view executes actions via the dispatcher.
Actions update the store (state) via reducers.
The store updates the view via connect() to react props.
This is what you see… Too simple. How do I make a server request??
Source: https://github.com/reactjs/redux/blob/master/examples/todomvc/actions/index.js
The key is always return a new object when you manipulate the store. It lets redux optimize react render passes.
Source: https://github.com/reactjs/redux/blob/master/examples/todomvc/reducers/todos.js
Ok so that's what you (probably) already knew about redux.
If you’re use Python’s record type or Ruby’s struct… it’s just like that. Easy peasy data classes.
Immutability is pretty much essential for redux because of how it optimizes updates.
Immutable.js is definitely cleaner than using Object.assign and spread/ rest to create new objects. (It’s also faster.)
If you’re use Python’s record type or Ruby’s struct… it’s just like that. Easy peasy data classes.
Immutability is pretty much essential for redux because of how it optimizes updates.
Immutable.js is definitely cleaner than using Object.assign and spread/ rest to create new objects. (It’s also faster.)
Should stores hold a single object? A list if it’s
I’ve got a list of nested items on the left… So immediately I know I need stores to hold a sequence of items.
But also I need to be able to determine relations between items. (Normalizr helps with this.)
In addition to the same item appearing both in the list and the main section.
Long term you might want something like an LRU to deal with paging and data bloat.
I need to be able to determine relations between items. (Normalizr helps with this.)
I decided stores should be maps of my domain models. They have child/parent ID references so you can lookup corresponding parent children in each store.
Long term you might want something like an LRU to deal with paging and data bloat.
The reason why actions are disconnected from reducers is because they are not always 1-to-1.
On line 35 the transmitter (child) reducer is populating the store from children in a fetched parent object.
Let's look at connecting your store to view components.
The connect method of react-redux is awesome.
• Components are completely unaware of redux.
• Connect() wrapped components have stores (state) and actions injected into props.
• This makes un-connected components easily testable.
• If you've done Java/Spring this feels like dependency injection
This is why you need redux-thunk. Basically to do anything async.
IDK why it’s not part of redux or react-redux.
When you execute your action, return the promise and you can do things like navigation, close a dialog, etc. when the action completes.
On line 81 I’m calling an action then closing a dialog and navigating to a new page (line 83) when successful.
I could also perform specific steps if the action failed (e.g. 409 conflict on the server)
If you ask me this is more appropriate place to put this logic than e.g. by getting a result from a store.
Components wrapped in connect() can’t be searched for by Component name in shallow render tests. :(
Erik Ras proposes exposing both a connected and non-connected component. See: https://github.com/erikras/ducks-modular-redux
But testing stores is trivial!!!
The connect() method has a workaround: see the `withRef` option.
https://github.com/reactjs/react-redux/blob/master/docs/api.md
This is actually a perfect example of how react state “traps” the application state.
Instead of calling a method to get or change a component’s state, consider passing it from child to parent via a callback, and/or changing by dispatching a redux action.
• Benefit: any part of the view heirarchy can now manipulate that state. E.g. a root view closing all dialogs.
• Line 23 is calling a redux action.
• Line 29 is an example of calling `closeDialogAction` in a promise chain
The connect() method has a workaround: see the `withRef` option.
https://github.com/reactjs/react-redux/blob/master/docs/api.md
Should stores hold a single object? A list if it’s
Actions that might be required by multiple disconnected components (e.g. initial data on page load) can easily be debounced to multiple expensive requests.
This is how I manage the loading state.
actionStarted() dispatches a loading increment action
dispatchActionComplete() and dispatchError() does a decrement.
Redux form solves the problem of trapping current form value in state
Code for validation is trivial
Andrew did a great presentation last month about React.js and I don’t think he used any flux framework.
It works!
• The unidirectional data flow does great things by itself.
• You can build the rest (remote calls + app state) without too much effort.
I’m thinking about ordering some shirts on Teespring – who’s interested? :D
The end.
I work at VoltServer – we make some pretty cool power disitribution technology.
Ask me about Digital Electricity. It’s pretty rad.
Extra stuff if there are questions.
Actions are simple… Really simple.
Replaced standard fetch actions with thunks to create cookie-cutter actions.
Actions that might be required by multiple disconnected components (e.g. initial data on page load) can easily be debounced to multiple expensive requests.