For the past two days I’ve been into Redux. It’s a framework-agnostic JavaScript library for easier handling of all application’s state. Specialty of Redux is that application state is stored in one object (and not different object for different data domain) and that functions reducers
which manipulates part of the state never mutate it but return rather new state.
Redux has really good documentation and couple of official examples with various difficulty and that’s where I started. I’ve read two introductory chapter and chapter about basics, studied the three simplest example applications (vanilla counter
, counter
and todos
) trying to memorize how different parts fit together. Then I went on studying async
example in the next chapter, which is basically only about how to do server calls and then updating application state. I’ve also studied shoping-cart
which is slightly richer example. I’d like to stress that things didn’t clicked right away but after couple of rereads and a sleep they started to click, I just had to be patient.
For exercise I decided to apply idea of async
example to todos
example. It went really well. Here is a recap of what was added to load posts from server when user opens the web application (I’ve skipped informing state about beginning of posts fetching since it was nothing new):
actions/index.js
import fetch from 'isomorphic-fetch'
// existing code left out for brevity
export const receivedTodos = posts => {
return {
type: 'TODOS_RECEIVED',
posts
}
}
export const fetchTodos = () => {
return dispatch => {
fetch('http://localhost:3000/todos')
.then(data => data.todos)
.then((todos) => dispatch(receivedTodos(todos)))
};
}
reducers/todos.js
const todos = (state = [], action) => {
// ...
case 'TODOS_RECEIVED':
return action.posts
default:
return state
}
}
main.js
import 'babel-polyfill'
import 'es6-promise' // added
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
import thunkMiddleware from 'redux-thunk'
import createLogger from 'redux-logger'
import todoApp from './reducers'
import App from './components/App'
import { fetchTodos } from './actions'
let store = createStore(
todoApp,
{},
applyMiddleware(thunkMiddleware, createLogger())
)
store.dispatch(fetchTodos());
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)