Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)
-
Upload
indeedeng -
Category
Engineering
-
view
569 -
download
1
Transcript of Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)
![Page 1: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/1.jpg)
Indeed My JobsA case study in ReactJS and Redux
![Page 2: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/2.jpg)
Gaurav MathurSoftware Engineer
![Page 3: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/3.jpg)
I help people get jobs.
![Page 4: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/4.jpg)
![Page 5: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/5.jpg)
![Page 6: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/6.jpg)
![Page 7: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/7.jpg)
![Page 8: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/8.jpg)
What happens next?
![Page 9: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/9.jpg)
Following up
![Page 10: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/10.jpg)
Scheduling an interview
![Page 11: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/11.jpg)
Preparing an interview
![Page 12: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/12.jpg)
Negotiating your offer
![Page 13: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/13.jpg)
Making a decision
![Page 14: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/14.jpg)
![Page 15: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/15.jpg)
![Page 16: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/16.jpg)
Why React?
![Page 17: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/17.jpg)
Virtual DOM
![Page 18: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/18.jpg)
JSX
![Page 19: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/19.jpg)
Data flow
![Page 20: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/20.jpg)
![Page 21: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/21.jpg)
MainDisplay
![Page 22: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/22.jpg)
ViewList
![Page 23: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/23.jpg)
JobTable
![Page 24: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/24.jpg)
JobRow
![Page 25: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/25.jpg)
MainDisplay
ViewListJobTable
JobRow
![Page 26: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/26.jpg)
MainDisplayState: jobs, counts
ViewListJobTable
JobRow
![Page 27: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/27.jpg)
Props: counts
MainDisplayState: jobs, counts
ViewListJobTable
JobRow
![Page 28: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/28.jpg)
MainDisplayState: jobs, counts
ViewListJobTable
JobRow
Props: jobs, updateHandler
![Page 29: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/29.jpg)
MainDisplayState: jobs, counts
ViewListJobTable
JobRow
Props: job, updateHandler
![Page 30: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/30.jpg)
![Page 31: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/31.jpg)
JobRow
MainDisplay
ViewListJobTable
this.props.handleUpdate(job, state)
![Page 32: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/32.jpg)
this.props.handleUpdate(job, state)
JobRow
MainDisplay
ViewListJobTable
![Page 33: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/33.jpg)
this.setState({jobs:newJobs, counts:newCounts});
JobRow
MainDisplay
ViewListJobTable
![Page 34: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/34.jpg)
this.render(); //automatically fired
JobRow
MainDisplay
ViewListJobTable
![Page 35: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/35.jpg)
Component
Component
Component
Component
this.props.handleUpdate(job, state)
this.props.handleUpdate(job, state)
this.props.handleUpdate(job, state)
![Page 36: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/36.jpg)
![Page 37: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/37.jpg)
Flux
![Page 38: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/38.jpg)
View
![Page 39: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/39.jpg)
View
Action
![Page 40: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/40.jpg)
View
Dispatcher
Action
![Page 41: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/41.jpg)
View
Dispatcher
StoreAction
![Page 42: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/42.jpg)
View
Dispatcher
StoreAction
![Page 43: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/43.jpg)
![Page 44: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/44.jpg)
Transition the job
Transition Job
Job Row
Action = { type: JobActions.APPLY, job: job};
![Page 45: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/45.jpg)
Dispatch the action
MyJobsDispatcher.handleAction({ type: JobActions.APPLY, job: job});
Transition Job
Dispatcher
Job Row
![Page 46: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/46.jpg)
function handleChange(action) { ... switch (action.type) { case JobActions.APPLY: job.set('state', States.APPLIED); break; ... } JobStore.emitChange();}JobStore.dispatchToken = MyJobsDispatcher.register(handleChange);
Update Job Store
Transition Job
Dispatcher
Job Store
Job Row
![Page 47: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/47.jpg)
function handleChange(action) { MyJobsDispatcher.waitFor( [JobStore.dispatchToken] ); ... JobCountsStore.emitChange();}
Update Job Counts
Transition Job
Dispatcher
Job StoreJob Count Store
Job Row
![Page 48: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/48.jpg)
ListenableStore.prototype = { emitChange() { for (let i = 0; i < this.listeners.length; i++) { this.listeners[i](); } }, ...}
Listen for changes
![Page 49: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/49.jpg)
const changeAggregator = new ChangeAggregator( MyJobsDispatcher, storesToListenTo);const MainDisplay = React.createClass({ componentDidMount() { changeAggregator.addChangeListener(this.update); } ...});
Collect changes
![Page 50: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/50.jpg)
const MainDisplay = React.createClass({ ... update() { this.setState({ jobs: JobStore.getJobs(), counts: JobCountStore.getCounts(), ... }); }});
Transition Job
Dispatcher
Job StoreJob Count Store
Job Row
View List Job Table
Update views
![Page 51: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/51.jpg)
Shortcomings
![Page 52: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/52.jpg)
Boilerplate
ListenableStore
ChangeAggregator
MyjobsDispatcher
![Page 53: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/53.jpg)
Best Practices & Testability
// TODO: Should this be in a different place..?window.scrollTo(0, 0);ViewStore.emitChange();
ViewStore.js
![Page 54: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/54.jpg)
Borrowed from: https://twitter.com/denisizmaylov/status/672390003188703238
![Page 55: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/55.jpg)
Jing WangSoftware Engineer
![Page 56: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/56.jpg)
I help people get jobs.
![Page 57: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/57.jpg)
Borrowed from: https://twitter.com/denisizmaylov/status/672390003188703238
![Page 58: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/58.jpg)
Single source of truth
![Page 59: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/59.jpg)
Application State Tree
![Page 60: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/60.jpg)
State is read only
![Page 61: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/61.jpg)
Dispatcher & Actions
![Page 62: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/62.jpg)
Pure functions
![Page 63: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/63.jpg)
Reducers
![Page 64: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/64.jpg)
Redux Store
![Page 65: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/65.jpg)
Single source of truthconst createStore = (reducer) => { let state = {}; const getState = () => state; let listeners = []; const subscribe = (listener) => { listeners.push(listener); } const dispatch = (action) => { state = reducer(state, action); listeners.forEach(listener => listener()); }; return {getState, dispatch, subscribe};}
![Page 66: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/66.jpg)
State is read onlyconst createStore = (reducer) => { let state = {}; const getState = () => state; let listeners = []; const subscribe = (listener) => { listeners.push(listener); } const dispatch = (action) => { state = reducer(state, action); listeners.forEach(listener => listener()); }; return {getState, dispatch, subscribe};}
![Page 67: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/67.jpg)
Changes are made with pure functionsconst createStore = (reducer) => { let state = {}; const getState = () => state; let listeners = []; const subscribe = (listener) => { listeners.push(listener); } const dispatch = (action) => { state = reducer(state, action); listeners.forEach(listener => listener()); }; return {getState, dispatch, subscribe};}
![Page 68: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/68.jpg)
Emit changesconst createStore = (reducer) => { let state = {}; const getState = () => state; let listeners = []; const subscribe = (listener) => { listeners.push(listener); } const dispatch = (action) => { state = reducer(state, action); listeners.forEach(listener => listener()); }; return {getState, dispatch, subscribe};}
![Page 69: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/69.jpg)
Single reducerconst createStore = (reducer) => { let state = {}; const getState = () => state; let listeners = []; const subscribe = (listener) => { listeners.push(listener); } const dispatch = (action) => { state = reducer(state, action); listeners.forEach(listener => listener()); }; return {getState, dispatch, subscribe};}
![Page 70: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/70.jpg)
const myjobsReducer(state = new AppState(), action) => { state = state.set('jobs', jobsReducer(state.jobs, action)); state = state.set('jobCounts', jobCountsReducer(state.jobCounts, action, state.jobs)); ... return state;}
Combining reducers
![Page 71: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/71.jpg)
const myjobsStore = createStore(myjobsReducer);<MainDisplay store={myjobsStore} .../>
Store as an explicit prop
![Page 72: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/72.jpg)
const myjobsStore = createStore(myjobsReducer);<MainDisplay store={myjobsStore} .../><ViewList store={this.props.myjobsStore} .../>
Store as an explicit prop
![Page 73: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/73.jpg)
const myjobsStore = createStore(myjobsReducer);<MainDisplay store={myjobsStore} .../><ViewList store={this.props.myjobsStore} .../><JobTable store={this.props.myjobsStore} .../>
Store as an explicit prop
![Page 74: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/74.jpg)
react-redux Providerconst myjobsStore = createStore(myjobsReducer);<Provider store={myjobsStore}> <MainDisplay /></Provider>
MainDisplay
Provider
myjobsStore
![Page 75: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/75.jpg)
const myjobsStore = createStore(myjobsReducer);<Provider store={myjobsStore}> <MainDisplay /></Provider>
react-redux Provider
JobRow
MainDisplay
ViewListJobTable
Provider
myjobsStore
Provided store: {myjobsStore}
![Page 76: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/76.jpg)
connect(mapStateToProps, mapDispatchToProps, ...) {}
react-redux connect
![Page 77: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/77.jpg)
mapStateToProps
function mapStateToProps(state) { return { jobsState: state.jobs };}
![Page 78: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/78.jpg)
const mapDispatchToProps = (dispatch) => { return { handleAction: (action) => { dispatch(action); } };}
mapDispatchToProps
![Page 79: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/79.jpg)
connect(mapStateToProps, mapDispatchToProps, ...) { ... return function wrapWithConnect(WrappedComponent) { class Connect extends Component { ... return Connect; }; }}
react-redux connect
![Page 80: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/80.jpg)
react-redux connect
Connect
constructor(props, context) { this.store = props.store || context.store; this.state = { this.store.getState() };};
![Page 81: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/81.jpg)
Connect
...componentDidMount() { this.store.subscribe(this.handleChange.bind(this));}handleChange() { this.setState({ this.store.getState() })}
react-redux connect
![Page 82: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/82.jpg)
Connect
...render() { this.renderedElement = createElement( WrappedComponent, this.mergedProps ); return this.renderedElement;}
react-redux connect
![Page 83: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/83.jpg)
Connect
...render() { this.renderedElement = createElement( WrappedComponent, this.mergedProps ); return this.renderedElement;}
mergedProps: { ...parentProps, ...mapStateToProps, ...mapDispatchToProps}
react-redux connect
![Page 84: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/84.jpg)
import { connect } from 'react-redux';...const matchStateToProps => (state) { return { jobsState: state.jobs };}module.exports = connect(matchStateToProps)(JobTable);
JobTable.js
![Page 85: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/85.jpg)
JobRow.js
import { connect } from 'react-redux';...module.exports = connect()(JobRow);
![Page 86: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/86.jpg)
Connect
Connect Connect
Connect
JobRow
MainDisplay
ViewListJobTable
![Page 87: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/87.jpg)
![Page 88: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/88.jpg)
const createStore = (reducer) => {... const dispatch = (action) => { state = reducer(state, action); listeners.forEach(listener => listener()); };}
myjobsStore{type:"APPLY",jobKey:"7b14...",...}
Job Row
![Page 89: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/89.jpg)
const createStore = (reducer) => {... const dispatch = (action) => { state = reducer(state, action); listeners.forEach(listener => listener()); };}
Job Row
myjobsStore
myjobsReducer
state
![Page 90: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/90.jpg)
const createStore = (reducer) => {... const dispatch = (action) => { state = reducer(state, action); listeners.forEach(listener => listener()); };}
Job Row
myjobsStore
myjobsReducer
state
newState
![Page 91: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/91.jpg)
const createStore = (reducer) => {... const dispatch = (action) => { state = reducer(state, action); listeners.forEach(listener => listener()); };}
JobTable
Job Row
myjobsStore
myjobsReducer
state
newState
![Page 92: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/92.jpg)
jobReducerJobStore
Flux stores to Redux reducers
...
Flux Redux
jobCountsReducerJobCountsStore
![Page 93: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/93.jpg)
... store.subscribe(() => { if (view !== newView) { window.scrollTo(0, 0); } });
Side effects in separate handlers
![Page 94: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/94.jpg)
Less boilerplate code
createStoreListenableStoreChangeAggregatorMyJobsDispatcher
Flux ReduxFlux Redux
![Page 95: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/95.jpg)
Less boilerplate code
connectaddChangeListener(
)JobStore.getJobs()
Flux Redux
![Page 96: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/96.jpg)
Less boilerplate code
combineReducerswaitFor()
Flux Redux
![Page 97: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/97.jpg)
Easier to unit test
![Page 98: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/98.jpg)
Well unit tested state transition logic
Less code to maintain
Code easier to follow
Results
![Page 99: Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)](https://reader035.fdocuments.us/reader035/viewer/2022062503/58ed1a0b1a28ab8e208b4699/html5/thumbnails/99.jpg)
engineering.indeed.com
www.indeed.jobs