71
// webpack.config.js
const Encore = require(
'@symfony/webpack-encore'
);
Encore
// ...
.enableReactPreset();
module.exports = Encore.getWebpackConfig();
Slide 72
Slide 72 text
72
// app.js
import ReactDOM from 'react-dom';
import {App} from './App.js';
ReactDOM.render(
,
document.getElementById('portfolio')
);
Slide 73
Slide 73 text
73
// app.js
import ReactDOM from 'react-dom';
import {App} from './App.js';
ReactDOM.render(
,
document.getElementById('portfolio')
);
Tree of components
Slide 74
Slide 74 text
74
4.
Redux
Slide 75
Slide 75 text
75
One component
=
One state object
Slide 76
Slide 76 text
76
In a real React application,
you will soon have dozens
of React components
Slide 77
Slide 77 text
77
That’s a lot of states
Slide 78
Slide 78 text
78
How to synchronize them ?
Slide 79
Slide 79 text
79
Redux
Slide 80
Slide 80 text
80
Redux helps you manage a
single State for your whole
application and use it in
your components
Slide 81
Slide 81 text
81
Redux works using
Actions
and
Reducers
Slide 82
Slide 82 text
82
Your components receive
data from global state as
props
Slide 83
Slide 83 text
83
Your components dispatch
actions with custom data
Slide 84
Slide 84 text
84
Reducers transform these
actions into changes to the
global state
Slide 85
Slide 85 text
85
Global state
Initial global state Redux
Slide 86
Slide 86 text
86
Global state
Initial global state
Props
View
Props
View
Redux
Component
Component
mapStateToProps
Slide 87
Slide 87 text
87
Global state
Initial global state
Dispatcher
Props
View
Props
View
Redux
Component
Component
mapStateToProps
dispatch
Slide 88
Slide 88 text
88
Global state
Initial global state
Dispatcher
Props
View
Props
View
Redux
Component
Component
mapStateToProps
dispatch
Reducers
Slide 89
Slide 89 text
89
5.
Example
Slide 90
Slide 90 text
90
SymfonyInsight
Portfolio
Slide 91
Slide 91 text
91
Slide 92
Slide 92 text
92
Global state
{
dateInterval: string,
isLoading: boolean,
projects: Project[] | null,
lastUpdated: Date | null,
}
101
import {storage} from '../storage/storage';
export const dateIntervalReducer = (state, action) => {
if (typeof state === 'undefined') {
return storage.get('portfolio-date-interval', 2);
}
switch (action.type) {
case 'SET_DATE_INTERVAL':
storage.set('portfolio-date-interval', action.dateInterval);
return action.dateInterval;
default:
return state;
}
};
Slide 102
Slide 102 text
102
import {storage} from '../storage/storage';
export const dateIntervalReducer = (state, action) => {
if (typeof state === 'undefined') {
return storage.get('portfolio-date-interval', 2);
}
switch (action.type) {
case 'SET_DATE_INTERVAL':
storage.set('portfolio-date-interval', action.dateInterval);
return action.dateInterval;
default:
return state;
}
};
Current state
Slide 103
Slide 103 text
103
import {storage} from '../storage/storage';
export const dateIntervalReducer = (state, action) => {
if (typeof state === 'undefined') {
return storage.get('portfolio-date-interval', 2);
}
switch (action.type) {
case 'SET_DATE_INTERVAL':
storage.set('portfolio-date-interval', action.dateInterval);
return action.dateInterval;
default:
return state;
}
};
Current state
Initial state
Slide 104
Slide 104 text
104
import {storage} from '../storage/storage';
export const dateIntervalReducer = (state, action) => {
if (typeof state === 'undefined') {
return storage.get('portfolio-date-interval', 2);
}
switch (action.type) {
case 'SET_DATE_INTERVAL':
storage.set('portfolio-date-interval', action.dateInterval);
return action.dateInterval;
default:
return state;
}
};
Current state
Initial state
New state