React+Redux
Meet React
A JavaScript Library for Building User Interfaces
How does React compare to other frameworks?
React is only the view layer
Why is React so compelling?
1. declarative → predictable → confidence → reliable
2. Composable
3. Server Rendering
4. Works great with teams
Virtual DOM
What about the code?
Create-react-app
Create React apps with no build configuration.
Release date: 22/07/2016
// Install it globally
npm install -g create-react-app
// Creates new React app
create-react-app my-app
cd my-app
// Runs app in development mode.
// Server listening on localhost:8080
npm start
// Builds the app for production
npm run build
// Switch to advanced mode
npm run eject
Render method
Render a React Element into the DOM
ReactDOM.render(
<h1>Hello world!</h1>, // Element
document.getElementById('root') // Root node container
);
- Starting point of any React app
- Transforms the Virtual DOM into the real DOM
Components
Fundamental block of UI
React.createClass({
render: function() {
return <h1>Hello world!</h1>
}
});
- A React Component is a highly cohesive building block for UI, loosely coupled with other components -
Component definition
Using createClass method
var Title = React.createClass({
render: function() {
return <h1>Hello world!</h1>
}
});
Using ES6 classes
class Title extends React.Component {
render() {
return <h1>Hello world!</h1>
}
}
v.0.13 +
To sum up
Create the component
var Title = React.createClass({
render: function() {
return <h1>Hello world!</h1>
}
});
And render it into the DOM
ReactDOM.render(
<Title/>,
document.getElementById('root')
);
Voilà, our first component
See the Penrender method example by Diego Muracciole (@diegomura) onCodePen.
That's great, but...
Is that HTML inside our JS !?
JSX
Optional preprocessor to use HTML-like syntax in our code
React.createClass({
render: function() {
return <h1>Hello world!</h1>
}
});
⟹
React.createClass({
render: function() {
return React.createElement(
'h1', // Element type
null, // Props
"Hello world!" // Children
)
}
});
JSX Gotchas
<h1 class="foo">Hello, world⟹<h1 className="foo">Hello, world
<label for="some-input">Inpu⟹<label htmlFor="some-input">Inpu
Component props
Read-only properties passed to a React Component via its attributes
We can access these properties inside the components via the this.props object
<Title
color="red"
fontSize="2em"
hidden={true}
/>
⟹
this.props = {
color: 'red',
fontSize: '2em',
hidden: true,
// ...
}
PropTypes
They define what props your Component needs and what type(s) they should be
The isRequired property tells that the property is required for the Component to work
Using createClass method
var Serie = React.createClass({
propTypes: {
name: React.PropTypes.string.isRequired,
seasons: React.PropTypes.number
},
render: function() { /* ... */ }
});
Using ES6 classes
class Serie extends React.Component {
render() { /* ... */ }
}
Serie.propTypes = {
name: React.PropTypes.string.isRequired,
seasons: React.PropTypes.number
}
JS primitive types
- array
- bool
- func
- number
- object
- string
- symbol
Others
- node
- element
- instanceOf()
- oneOf([])
- oneOfType([])
- arrayOf()
- objectOf()
- shape({})
- any
DefaultProps
They define props default values in case they are not passed in
Using createClass method
var Serie = React.createClass({
defaultProps: {
name: 'Game of Thrones'
seasons: 1
},
render: function() { /* ... */ }
});
Using ES6 classes
class Serie extends React.Component {
render() { /* ... */ }
}
Serie.defaultProps = {
name: 'Game of Thrones'
seasons: 1
}
See the Pen props example by Diego Muracciole (@diegomura) on CodePen.
Component state
Initial state
Using createClass method
var Serie = React.createClass({
getInitialState: function() {
return {
likes: 0,
// ...
}
},
render: function() { /* ... */ }
});
Using ES6 classes
class Serie extends React.Component {
constructor(props) {
super(props);
this.state = {
likes: 0,
//...
}
}
render() { /* ... */ }
}
Change component state
setState Method
this.setState(nextState);
- Primary method to trigger UI updates unless shouldComponentUpdate() is false
- Merge the nextState into current state
Example
var Serie = React.createClass({
getInitialState: function() {
return { likes: 0, /* ... */ }
},
like: function() {
this.setState({
likes: this.state.likes + 1
})
},
render: function() { /* ... */ }
});
See the Pen state example by Diego Muracciole (@diegomura) on CodePen.
Component lifecycle
Lifecycle callbacks
React.createClass({
componentWillMount: function() { /* ... */ },
componentDidMount: function() { /* ... */ },
componentWillReceiveProps: function(nextProps) { /* ... */ },
shouldComponentUpdate: function(nextProps, nextState) { /* ... */ },
componentWillUpdate: function(nextProps, nextState) { /* ... */ },
componentDidUpdate: function(nextProps, nextState) { /* ... */ },
componentWillUnmount: function() { /* ... */ },
render: function() { /* ... */ }
});
See the Pen lifecycle example by Diego Muracciole (@diegomura) on CodePen.
Flux
Flux is more of a pattern than a framework
Data flow
Flux cartoon guide by @linclark
User triggers an action
View tells the Action Creator to prepare the action
Action Creator formats the action and dispatch it
Dispatcher sends the action to the stores
Stores change the state and notifiy subscribed views controllers
View Controller ask for new state and updates the view
Meet Redux
Predictable state container for JavaScript apps
1st principle of Redux
The single immutable state tree
State
{
series: [
{
id: 1,
name: 'Game of Thrones',
seasons: 6,
likes: 0
},
// ...
]
}
2nd principle of Redux
The state is read-only. The only way to change it is by dispatching an action
Action
Minimal representation of a state change
{
type: 'LIKE', // Type is mandatory
serie_id: 1,
// ...
}
Reducer function
Pure function that describes how the state mutates given an action
Pure functions
1- Output depends only on the given arguments
2- Function doesn't mutate arguments
🚫
function append(array, item) {
item = api_call(item);
return arra.push(item);
}
✅
function append(array, item) {
return array.concat(item);
}
Array.reduce((accumulator, value) => accumulator)
Array.reduce((accumulator, value) => accumulator)
reducer(state, action) => state
const reducer = (state = 0, action) => {
switch(action.type) {
case 'LIKE':
return state + action.increment
default:
return state;
}
}
Store
Binds Redux principles into one object
const store = Redux.createStore(reducer)
Store main methods
getState()
Returns: current state
dispatch(action)
Arguments: action to be dispatched
Returns: dispatched action
subscribe(callback)
Arguments: callback that will be called any time an action is dispatched
See the Pen redux example by Diego Muracciole (@diegomura) on CodePen.