Building a Mini-Instagram with React + Redux
Steven Petryk
@stevenpetryk
What is Redux?
(props) => UI
React gave us the concept of:
import React from 'react'
export default ({
className,
children,
...rest
}) => (
<div className={`button ${className}`} {...rest}>
{children}
</div>
)
What is Redux?
(state, action) => nextState
And Redux brings us the reducer:
export function photos (state = [], action) {
switch (action.type) {
case 'ADD_PHOTO':
return [
...state,
action.photo
]
default:
return state
}
}
Where state is held in a global store.
Actions are dispatched by you.
Actions
{
type: 'ADD_PHOTO',
photo: {
id: 18,
src: 'http://i.imgur.com/X1kILq9.jpg',
alt: 'Hey lil guy'
}
}
An action describes what to do.
(in case you were wondering)
It doesn't specify how.
The Datapath
Store
Action
Reducer 1
Reducer 2
Reducer 3
nextState = r3(r2(r1(state, action), action), action)
uhhh
You know what? Let's just code.
#learnbydoing
Tying into React
Redux only describes the data layer.
We need to take this:
(props) => UI
And turn it into this:
(state, dispatch) => (props) => UI
Tying into React
Think of your average functional React component:
export default const Photo = ({
photo,
onLike
}) => (
<div className='photo' onDoubleClick={onLike}>
<img src='photo' src={photo.src} />
</div>
)
- src is a prop that comes from the state.
- onLike is a callback that modifies state.
Tying into React
We could wrap this component like so:
import Photo from './Photo'
export default const PhotoContainer = ({
store,
photoId
}) => {
// Mapping state to props
const photo = store.getState().photos[photoId]
// Mapping action creators to props
function onLike () {
store.dispatch({
type: 'LIKE_PHOTO',
payload: {
photoId
}
})
}
return <Photo { ...{photo, onLike} } />
}
Separating concerns reveals what we need.
import Photo from './Photo'
export default const PhotoContainer = ({
store,
...props
}) => (
<Photo {
...mapStateToProps(store.getState(), props),
...mapDispatchToProps(store.dispatch, props)
} />
)
function mapStateToProps (state, ownProps) {
return {
photo: state.photos[ownProps.photoId]
}
}
function mapDispatchToProps (dispatch, ownProps) {
return {
onLike () {
dispatch({
type: 'LIKE_PHOTO',
payload: { photoId: ownProps.photoId }
})
}
}
}
Meet React-Redux
(state, dispatch) => props => UI
import { connect } from 'react-redux' // aw hell yeah
import Photo from './Photo'
function mapStateToProps (state, ownProps) {
return {
photo: state.photos[ownProps.photoId]
}
}
function mapDispatchToProps (dispatch, ownProps) {
return {
onLike () {
dispatch({
type: 'LIKE_PHOTO',
payload: { photoId: ownProps.photoId }
})
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Photo)
Time to build something.
Thank you!
Steven Petryk
@stevenpetryk
Full-stack dev at Teeps.org
Building a Mini-Instagram with React+Redux
By Steven Petryk
Building a Mini-Instagram with React+Redux
For the first break in the slides, I fiddled with this: https://runkit.com/stevenpetryk/582a50bcf5baa400148abf44 For the second break in the slides, I coded this: https://github.com/stevenpetryk/react-redux-example
- 915