Redux 101
Disclaimer
I'm not an expert in this stuff, I've only been messing with it for a few weeks. If you see anything that's inaccurate please let me know so we can all learn together.
Redux is just a state container for javascript apps
What is Redux?
You can use it with any library, but it's pretty popular with React
The whole state of your app is stored in an object tree inside a single store. The only way to change the state tree is to emit an action, an object describing what happened. To specify how the actions transform the state tree, you write pure reducers.
The Redux documentation does a pretty good job of explaining it.
Let's go a bit deeper
Actions
Actions are payloads of information that send data from your application to your store. They are the only source of information for the store. You send them to the store using store.dispatch().
What they look like
{
type: 'ADD_TODO',
text: 'Build my first Redux app'
}
Actions are just plain objects. They must have a type, but other than that the structure is up to you.
Action Creators
function addTodo(text) {
return {
type: 'ADD_TODO',
text // equivalent to text: text
}
}
A lot of people roll actions into an action creator to make it a bit easier to deal with. Pretty much you're just saving yourself from having to put the type in there.
Reducers
Actions describe the fact that something happened but don’t specify how the application’s state changes in response. This is the job of a reducer. Reducers tell the state how to react based on the action.
What they look like
function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
The reducer takes in the state and action. The function returns different values based on the type of the action.
Store
Stores are not terribly exiting. They are just a place to hold our state.
// Creation of the store, holds the application state
let store = createStore(counter);
// Accessing the state
store.getState();
// Updating the state
store.dispatch(action);
// Dispatching will call ALL reducers. It's up to them to react to it.
// The store has a few other methods, but I don't know anything about them yet.
All Together
// This is our reducer
function counter(state, action) {
if (typeof state === 'undefined') {
return 0
}
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
// Create the store
var store = Redux.createStore(counter)
// Just getting some DOM, don't mind me.
var valueEl = document.getElementById('value')
// Every time the state changes we output it to the page
function render() {
valueEl.innerHTML = store.getState().toString()
}
render()
store.subscribe(render)
// Actually dispatching the actions when a user clicks things
document.getElementById('increment')
.addEventListener('click', function () {
store.dispatch({ type: 'INCREMENT' })
})
document.getElementById('decrement')
.addEventListener('click', function () {
store.dispatch({ type: 'DECREMENT' })
})
document.getElementById('incrementIfOdd')
.addEventListener('click', function () {
if (store.getState() % 2 !== 0) {
store.dispatch({ type: 'INCREMENT' })
}
})
document.getElementById('incrementAsync')
.addEventListener('click', function () {
setTimeout(function () {
store.dispatch({ type: 'INCREMENT' })
}, 1000)
})
Questions?
More
Redux 201
Using Redux with React
Components vs. Containers
What is this connect() thing?
Multiple Reducers
React & Redux
By brianjhanson
React & Redux
- 405