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:
const store = createStore(/* ... */)
// ...
ReactDOM.render(
,
node1
)
ReactDOM.render(
,
node2
)
And here’s how you can set reducers dynamically (they say, it’s how Twitter does it):
// 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;
// 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 });
// 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/
LEAVE A COMMENT
Для отправки комментария вам необходимо авторизоваться.