ReactJS Summary
1. Decompose UI into reusable components which
render to virtual DOM
2. ReactJS will sync VDOM to real browser DOM
3. JSX format
4. Can render on client and server
Redux - Three Principles
1. Single Source of Truth
The whole application must be described solely using a single
object: state
2. State is Read-only
The only way to change state is to emit an action
3. Changes are made with Pure Functions
Reducers are pure functions → No other variables involved (in or
out)
All actions pass through all reducers → ensure state is consistent
IN STATE WE TRUST
State: Single Source of Truth
$> console.log(store.getState())
{
visibilityFilter: 'SHOW_ALL',
todos: [
{
text: 'Consider using Redux',
completed: true,
},
{
text: 'Keep all state in a single tree',
completed: false
}
]
}
State is read only
The only way to mutate the state
is to dispatch an action → an object
describing what happened
store.dispatch({
type: 'COMPLETE_TODO',
index: 1
})
store.dispatch({
type: 'SET_VISIBILITY_FILTER',
filter: 'SHOW_COMPLETED'
})
State after action
State before action
Changes are made with REDUCERS
Reducers are pure functions.
Actions pass through all reducers
Never mutate state. Always return a new one
import {
combineReducers,
createStore
} from 'redux'
let reducer = combineReducers({ visibilityFilter, todos })
let store = createStore(reducer)
Changes are made with REDUCERS
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return [...state, {
text: action.text,
completed: false
}]
case 'COMPLETE_TODO':
return state.map((todo, index) => {
if (index === action.index) {
return Object.assign({}, todo, {
completed: true
})
}
return todo
})
default:
return state
}
}
function visibilityFilter(state =
'SHOW_ALL', action) {
switch (action.type) {
case 'SET_VISIBILITY_FILTER':
return action.filter
default:
return state
}
}
Connect React with Redux - mapStateToProps
import React, { Component } from 'react';
import { connect } from 'react-redux';
class MinionList extends Component {
createMinionMap() {
return this.props.minionList.map(minion => {
return (<MinionItem key={minion.id} minion={minion} />);
});
}
render() {
return (<ul className="col-md-10">{this.createMinionMap()}</ul>);
}
}
function mapStateToProps(state) {
return {
minionList: state.minionList
}
}
export default connect(mapStateToProps)(MinionList);
containers/minion_list.js
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options]) - React-redux
Connects a React component to a Redux store.
It does not modify the component class passed to it. Instead, it returns a new, connected component class, for you to use.
Connect React with Redux - Dispatch Action
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { searchMinion } from '../actions/index';
class SearchBar extends Component {
render() {
return (
<div>
<input onChange={event => this.onInputChange(event.target.value)} />
</div>);
}
onInputChange(term) {
this.props.searchMinion(term);
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ searchMinion }, dispatch);
}
export default connect(null, mapDispatchToProps)(SearchBar);
containers/search_bar.js
bindActionCreators(actionCreators, dispatch) - Redux
Turns an object whose values are action creators, into an object with the same keys, but with every action creator
wrapped into a dispatch call so they may be invoked directly.
Connect React with Redux - Make store connectable
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import App from './components/app';
import rootReducer from './reducers';
ReactDOM.render(
<Provider
store={createStore(rootReducer)}>
<App />
</Provider>
,
document.querySelector('.container'));
index.js
import { combineReducers } from 'redux';
import minionList from './minion_search';
import minionSelect from './minion_select';
const rootReducer = combineReducers({
minionList: minionList, //minionList
minionSelect: minionSelect //minionSelect
});
export default rootReducer;
reducers/index.js
<Provider store> - React-redux
Makes the Redux store available to the connect() calls in the component hierarchy below.
Connect React with Redux - Make store connectable
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import App from './components/app';
import rootReducer from './reducers';
ReactDOM.render(
<Provider
store={createStore(rootReducer)}>
<App />
</Provider>
,
document.querySelector('.container'));
index.js
import { combineReducers } from 'redux';
import minionList from './minion_search';
import minionSelect from './minion_select';
const rootReducer = combineReducers({
minionList: minionList, //minionList
minionSelect: minionSelect //minionSelect
});
export default rootReducer;
reducers/index.js
createStore(reducer, [initialState], [enhancer]) - Redux
Creates a Redux store that holds the complete state tree of your app.
There should only be a single store in your app.
Connect React with Redux - Make store connectable
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import App from './components/app';
import rootReducer from './reducers';
ReactDOM.render(
<Provider
store={createStore(rootReducer)}>
<App />
</Provider>
,
document.querySelector('.container'));
index.js
import { combineReducers } from 'redux';
import minionList from './minion_search';
import minionSelect from './minion_select';
const rootReducer = combineReducers({
minionList: minionList, //minionList
minionSelect: minionSelect //minionSelect
});
export default rootReducer;
reducers/index.js
combineReducers(reducers) - Redux
The combineReducers helper function turns an object whose values are different reducing functions into a single
reducing function you can pass to createStore.