This is the support of a course to teach mainly Redux, and Redux with React for Java and C# programmers. It is the third part of the course to recycle programmers from desktop app programming to web app programming. This course covers from history of Redux, its origin, step by step what is a reducer, and later concepts like reducer splitting, action handling, async and many more.
You also can use repositories:
- https://github.com/drpicox/learn-redux-bytesting
- https://github.com/drpicox/learn-redux-zoo-bytesting
To improve your skills.
13. MVC
MVP
MVVC
MVVM
MV*
Two key benefits of MV* are:
• "attach multiple views to a model to provide
different presentations"
• "change the way a view responds to user input
without changing its visual presentation"
15. “MVC works pretty well
for small applications…
but it doesn’t make room
for new features.”
“Flux is a single direction data flow,
that avoids all the arrows
going on all directions
what makes really
hard to understand the system.”
https://youtu.be/nYkdrAPrdcw?t=10m20s
28. Inspired in Flux
• Like Flux:
• Single direction data-flow
• Has actions
• Actions are dispatched
• Has stores concept
• Views subscribes to stores
28
29. Inspired in Flux
• Unlike Flux:
• One single store
> Single source of truth
• No dispatcher (dispatch by Store)
• State is computed with reducers
> State is read-only
> Changes are pure functions
• State is injected to views
29
30. Flux to Redux
const _todos = [];
const TodoStore = {...EventEmitter.prototype, {
getAll() {
return _todos;
},
});
AppDispatcher.register(function(action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
_todos.push(text);
TodoStore.emit('change');
}
});
export default TodoStore;
30
31. Flux to Redux
const _todos = [];
const TodoStore = {...EventEmitter.prototype, {
getAll() {
return _todos;
},
});
AppDispatcher.register(function(action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
_todos.push(text);
TodoStore.emit('change');
}
});
export default TodoStore;
31
32. Flux to Redux
const _todos = [];
const TodoStore = {...EventEmitter.prototype, {
getAll() {
return _todos;
},
});
export function handle(action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
_todos.push(text);
TodoStore.emit('change');
}
});
export default TodoStore;
32
33. Flux to Redux
const _todos = [];
const TodoStore = {...EventEmitter.prototype, {
getAll() {
return _todos;
},
});
export function handle(action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
_todos.push(text);
TodoStore.emit('change');
}
});
export default TodoStore;
33
34. Flux to Redux
let _todos = [];
const TodoStore = {...EventEmitter.prototype, {
getAll() {
return _todos;
},
});
export function handle(action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
_todos = [..._todos, text];
TodoStore.emit('change');
}
});
export default TodoStore;
34
35. Flux to Redux
let _todos = [];
const TodoStore = {...EventEmitter.prototype, {
getAll() {
return _todos;
},
});
export function handle(action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
_todos = [..._todos, text];
TodoStore.emit('change');
}
});
export default TodoStore;
35
36. Flux to Redux
let _todos = [];
const TodoStore = new EventEmitter();
export function getState() {
return _todos;
}
export function handle(action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
_todos = [..._todos, text];
TodoStore.emit('change');
}
});
export default TodoStore;
36
37. Flux to Redux
let _todos = [];
const TodoStore = new EventEmitter();
export function getState() {
return _todos;
}
export function handle(action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
_todos = [..._todos, text];
TodoStore.emit('change');
}
});
export default TodoStore;
37
38. Flux to Redux
let _todos = [];
export function getState() {
return _todos;
}
export function handle(action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
_todos = [..._todos, text];
}
});
38
39. Flux to Redux
let _todos = [];
export function getState() {
return _todos;
}
export function handle(action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
_todos = [..._todos, text];
}
});
39
40. Flux to Redux
let _todos = [];
export function handle(action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
_todos = [..._todos, text];
}
return _todos;
});
40
41. Flux to Redux
let _todos = [];
export function handle(action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
_todos = [..._todos, text];
}
return _todos;
});
41
42. Flux to Redux
export function handle(_todos, action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
_todos = [..._todos, text];
}
return _todos;
});
42
43. Flux to Redux
export function handle(_todos, action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
_todos = [..._todos, text];
}
return _todos;
});
43
44. Flux to Redux
export function handle(state, action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
state = [...state, text];
}
return state;
});
44
45. Flux to Redux
export function handle(state, action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
state = [...state, text];
}
return state;
});
45
46. Flux to Redux
export function handle(state, action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
return [...state, text];
default:
return state;
}
});
46
47. Flux to Redux
export function handle(state = [], action) {
switch (action.type) {
case ActionTypes.TODO_CREATE:
let text = action.text.trim();
return [..._todos, text];
default:
return state;
}
});
47
50. Actions
// actions are identified by type
const ADD_TODO = 'ADD_TODO'
// actions are always a JSON equivalent object
const exampleOfAction = {
type: ADD_TODO,
text: 'Learn Redux',
};
// we use function creators for actions
export function addTodo(text) {
return {type: ADD_TODO, text};
};
50
http://redux.js.org/docs/basics/Actions.html#source-code
52. State
// state is one single JSON object
{
visibilityFilter: 'SHOW_ALL',
todos: [
{
id: 123,
text: 'Learn Redux',
completed: false,
},
],
}
// state should be normalized (use pk/fk)
52
83. Presentational vs Container
83
Presentational Container
Purpose
How to render things
(html + css)
How things work
(fetch data, updates, ...)
Aware of Redux No Yes
To read data Read data from props Subscribe to Redux state
To change data Invoke callbacks from props Dispatch Redux actions
Written by hand usually by react-redux
84. Application
• Stores, reducers and actions are pure Redux
• Presentational components are pure React
• You may design them first
• Container components are the glue
• Design which data needs and which actions performs
• Decide which presentational components wrap
84
132. Selectors
• State should be single source of truth
• Normalized data
• No duplicated data
• Computed data can be obtained from state
• Compute under demand
• Memoize results
132