Leave a Comment
Multiple react applications on one page. Theory
Yes, it can be done.
That’s how you render several react apps on one page:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
const store = createStore(/* ... */) // ... ReactDOM.render( <Provider store={store}> <App1 /> </Provider>, node1 ) ReactDOM.render( <Provider store={store}> <App2 /> </Provider>, node2 ) |
And here’s how you can set reducers dynamically (they say, it’s how Twitter does it):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// data/reducerRegistry.js export class ReducerRegistry { constructor() { this._emitChange = null; this._reducers = {}; } getReducers() { return { ...this._reducers }; } register(name, reducer) { this._reducers = { ...this._reducers, [name]: reducer }; if (this._emitChange) { this._emitChange(this.getReducers()); } } setChangeListener(listener) { this._emitChange = listener; } } const reducerRegistry = new ReducerRegistry(); export default reducerRegistry; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
// data/notifications/index.js import reducerRegistry from '../reducerRegistry'; const initialState = []; let notificationId = 0; const reducerName = 'notifications'; const createActionName = name => `app/${reducerName}/${name}`; // reducer export default function reducer(state = initialState, action = {}) { switch (action.type) { case ADD_NOTIFICATION: return [...state, { ...action.payload, id: notificationId += 1 }]; case REMOVE_NOTIFICATION: return state.slice(1); default: return state; } } reducerRegistry.register(reducerName, reducer); // selectors export const selectAllNotifications = state => state[reducerName]; export const selectNextNotification = state => state[reducerName][0]; // actions export const ADD_NOTIFICATION = createActionName(ADD_NOTIFICATION); export const REMOVE_NOTIFICATION = createActionName(REMOVE_NOTIFICATION); // action creators export const addNotification = payload => ({ payload, type: ADD_NOTIFICATION }); export const removeNotification = () => ({ type: REMOVE_NOTIFICATION }); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// data/createStore.js import { combineReducers, createStore } from 'redux'; import reducerRegistry from './reducerRegistry'; const initialState = /* from local storage or server */ // Preserve initial state for not-yet-loaded reducers const combine = (reducers) => { const reducerNames = Object.keys(reducers); Object.keys(initialState).forEach(item => { if (reducerNames.indexOf(item) === -1) { reducers[item] = (state = null) => state; } }); return combineReducers(reducers); }; const reducer = combine(reducerRegistry.getReducers()); const store = createStore(reducer, initialState); // Replace the store's reducer whenever a new reducer is registered. reducerRegistry.setChangeListener(reducers => { store.replaceReducer(combine(reducers)); }); export default store; |
More details here:
https://github.com/reactjs/react-redux/issues/355
http://nicolasgallagher.com/redux-modules-and-code-splitting/
Similar Posts
LEAVE A COMMENT
Для отправки комментария вам необходимо авторизоваться.