Skip to content

Commit

Permalink
Add SET_STATE action, create reducer
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicolas Goutay committed Mar 27, 2016
1 parent aa101fc commit be48d4d
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 11 deletions.
2 changes: 2 additions & 0 deletions package.json
Expand Up @@ -46,6 +46,8 @@
"react": "^0.14.7",
"react-addons-pure-render-mixin": "^0.14.7",
"react-dom": "^0.14.7",
"react-redux": "^4.4.1",
"redux": "^3.3.1",
"todomvc-app-css": "^2.0.4"
}
}
12 changes: 11 additions & 1 deletion src/components/TodoApp.jsx
@@ -1,10 +1,11 @@
import React from 'react';
import {connect} from 'react-redux';
import TodoList from './TodoList'
import TodoHeader from './TodoHeader'
import TodoTools from './TodoTools'
import Footer from './Footer'

export default class TodoApp extends React.Component {
export class TodoApp extends React.Component {
getNbActiveItems() {
if (this.props.todos) {
const activeItems = this.props.todos.filter(
Expand All @@ -26,3 +27,12 @@ export default class TodoApp extends React.Component {
</div>
}
};

function mapStateToProps(state) {
return {
todos: state.get('todos'),
filter: state.get('filter')
};
}

export const TodoAppContainer = connect(mapStateToProps)(TodoApp);
29 changes: 19 additions & 10 deletions src/index.jsx
@@ -1,20 +1,29 @@
import React from 'react';
import ReactDOM from 'react-dom';
import {List, Map} from 'immutable';
import {createStore} from 'redux';
import {Provider} from 'react-redux';
import reducer from './reducer';
import {TodoAppContainer} from './components/TodoApp';

import TodoApp from './components/TodoApp';

const todos = List.of(
Map({id: 1, text: 'React', status: 'active', editing: false}),
Map({id: 2, text: 'Redux', status: 'active', editing: false}),
Map({id: 3, text: 'Immutable', status: 'completed', editing: false})
);

const filter = 'all';
const store = createStore(reducer);
store.dispatch({
type: 'SET_STATE',
state: {
todos: [
{id: 1, text: 'React', status: 'active', editing: false},
{id: 2, text: 'Redux', status: 'active', editing: false},
{id: 3, text: 'Immutable', status: 'active', editing: false},
],
filter: 'all'
}
});

require('../node_modules/todomvc-app-css/index.css');

ReactDOM.render(
<TodoApp todos={todos} filter={filter} />,
<Provider store={store}>
<TodoAppContainer />
</Provider>,
document.getElementById('app')
);
13 changes: 13 additions & 0 deletions src/reducer.js
@@ -0,0 +1,13 @@
import {Map} from 'immutable';

function setState(state, newState) {
return state.merge(newState);
}

export default function(state = Map(), action) {
switch (action.type) {
case 'SET_STATE':
return setState(state, action.state);
}
return state;
}
74 changes: 74 additions & 0 deletions test/reducer_spec.js
@@ -0,0 +1,74 @@
import {List, Map, fromJS} from 'immutable';
import {expect} from 'chai';

import reducer from '../src/reducer';

describe('reducer', () => {

it('handles SET_STATE', () => {
const initialState = Map();
const action = {
type: 'SET_STATE',
state: Map({
todos: List.of(
Map({id: 1, text: 'React', status: 'active'}),
Map({id: 2, text: 'Redux', status: 'active'}),
Map({id: 3, text: 'Immutable', status: 'completed'})
)
})
};

const nextState = reducer(initialState, action);

expect(nextState).to.equal(fromJS({
todos: [
{id: 1, text: 'React', status: 'active'},
{id: 2, text: 'Redux', status: 'active'},
{id: 3, text: 'Immutable', status: 'completed'}
]
}));
});

it('handles SET_STATE with plain JS payload', () => {
const initialState = Map();
const action = {
type: 'SET_STATE',
state: {
todos: [
{id: 1, text: 'React', status: 'active'},
{id: 2, text: 'Redux', status: 'active'},
{id: 3, text: 'Immutable', status: 'completed'}
]
}
};
const nextState = reducer(initialState, action);
expect(nextState).to.equal(fromJS({
todos: [
{id: 1, text: 'React', status: 'active'},
{id: 2, text: 'Redux', status: 'active'},
{id: 3, text: 'Immutable', status: 'completed'}
]
}));
});

it('handles SET_STATE without initial state', () => {
const action = {
type: 'SET_STATE',
state: {
todos: [
{id: 1, text: 'React', status: 'active'},
{id: 2, text: 'Redux', status: 'active'},
{id: 3, text: 'Immutable', status: 'completed'}
]
}
};
const nextState = reducer(undefined, action);
expect(nextState).to.equal(fromJS({
todos: [
{id: 1, text: 'React', status: 'active'},
{id: 2, text: 'Redux', status: 'active'},
{id: 3, text: 'Immutable', status: 'completed'}
]
}));
});
});

0 comments on commit be48d4d

Please sign in to comment.