This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // RENDER PAGE | |
| server.all('*', (req, res) => { | |
| const { store } = req; | |
| match({ routes, location: req.url }, (error, redirectLocation, renderProps) => { | |
| if (redirectLocation) { | |
| res.redirect(301, redirectLocation.pathname + redirectLocation.search); | |
| } else if (error) { | |
| res.status(500).send(error.message); | |
| } else if (!renderProps) { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Cats extends Component { | |
| static fetchData({ location, dispatch }) { | |
| return dispatch(setQueryParams(location.query)) | |
| .then(() => dispatch(getCats())); | |
| } | |
| componentDidMount() { | |
| Cats.fetchData(this.props); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const defaultState = { | |
| cats: [], | |
| filter: {}, | |
| didSetCats: false, | |
| }; | |
| const SET_CATS = 'cats/SET_CATS'; | |
| const SET_FILTER = 'cats/SET_FILTER'; | |
| export default (state = defaultState, action) { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const FETCH = '@@middleware/fetch/FETCH'; | |
| export default (baseUrl, fetchImplementation) => () => next => async action => { | |
| if (action.type === FETCH) { | |
| const { method, path, body } = action; | |
| const params = { method }; | |
| if (body) params.body = JSON.stringify(body); | |
| const url = baseUrl + path; | |
| const response = await fetchImplementation(url, params); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export const setCats = () => async (dispatch, getState) => { | |
| const cats = await dispatch(fetchJson('GET', '/cats', filter)); | |
| dispatch({ type: SET_CATS, cats }); | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { createStore, applyMiddleware, combineReducers } from 'redux'; | |
| const middlewares = applyMiddleware( | |
| thunk, | |
| fetchMiddleware(fetch, 'http://api.server.com') | |
| ); | |
| const store = createStore(reducers, initialState, middlewares); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const fetch = (url, params) => ({ | |
| type: 'FETCH', | |
| url, | |
| params, | |
| }); | |
| const fetchMiddleware = fetchImplementation => store => next => action => { | |
| if (action.type === 'FETCH') { | |
| const { url, params } = action; | |
| const token = store.getState().token; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const middleware = () => store => { | |
| const fileWatcher = new FileWatcher(); | |
| fileWatcher.on('file-changed', filename => { | |
| store.dispatch({ type: 'FILE_CHANGED', filename }); | |
| }); | |
| // Make sure we're watching files that may be included in the store's initial state | |
| const initialFiles = store.getState().activeFiles; | |
| fileWatcher.watchFiles(initialFiles); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const middleware = musicPlayer => store => { | |
| const playbackOrigin = 'playbackOrigin'; | |
| musicPlayer.on('current-time-changed', currentTime => { | |
| store.dispatch({ type: 'SET_CURRENT_TIME', origin: playbackOrigin, currentTime }); | |
| }); | |
| musicPlayer.on('playback-finished', () => { | |
| store.dispatch({ type: 'STOP_PLAYING', origin: playbackOrigin }); | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const middleware = () => store => next => action => { | |
| // Get the state before and after the action was performed | |
| const previousToken = store.getState().token; | |
| next(action); | |
| const nextToken = store.getState().token; | |
| // Respond to changes | |
| if (nextToken !== previousToken) localStorage.setItem('token', nextToken); | |
| }; |