WoodWorking for Mere Mortals
1 + 1 + 2 + 3 + 5 = 12
12 * 5 = 60
Redux is a predictable state container for JavaScript apps.
Created by Dan Abramov
const action = {
type: 'MY_ACTION_TYPE',
payload: 'the optional payload'
}
import * as types from './constants/actionTypes'
export function toggleAwesomeness () {
return { type: types.TOGGLE_AWESOMENESS }
}
const initialState = {
isAwesome: false
}
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'TOGGLE_AWESOMENESS':
return Object.assign({}, state, {
isAwesome: !state.isAwesome
})
default:
return state
}
}
Redux uses principles of functional programming. Thus, reducers should be pure functions, returning state that is derived solely from its inputs.
const initialState = {
collectionOfGoodies: [
{ id: 1, name: 'Cookies' },
{ id: 2, name: 'Pizza' },
{ id: 3, name: 'Beer' }
]
}
let nextId = 3
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'ADD_GOODIE':
return Object.assign({}, state, {
collectionOfGoodies: [
...state.collectionOfGoodies,
{
id: nextId++,
name: action.name
}
]
})
default:
return state
}
}
This, don't do this. That's bad. :(
Also known as "dumb" components, presentational components render based solely on props passed to them, with no internal state or lifecycle methods used.
Container components connect to the store and/or use lifecycle methods to update state and/or props to pass down props to presentational components
*Not idiomatic, a phrase I coined and a pattern I find useful
Renderless components contain app logic that utilizes lifecycle methods but does not need a UI
Provider and connect() are HOCs that come with the 'react-redux' package.
The `<Provider> wraps your application and passes the store down to "connected" components.
import React from 'react'
import { Provider } from 'react-redux'
import store from '../store'
const App = () => (
<Provider store={store}>
{/* Rest of my application structure */}
</Provider>
)
export default App
`connect()` allows us to bind state and actions to our component and pass them in as props. Thus, we do not need to import our store and call dispatches on the store, though this is a legitimate way to use Redux.
export class MyContainer extends Component {
// ...
}
const mapStateToProps = state => ({
isAwesome: state.isAwesome,
collectionOfGoodies: state.collectionOfGoodies
})
const mapDispatchToProps = {
toggleAwesomeness
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(MyContainer)
export class MyContainer extends Component {
// ...
}
export default connect(mapStateToProps)(MyContainer)