mail: vnovick@gmail.com
twitter: @VladimirNovick
github: vnovick
facebook: vnovickdev
SPA
SSR
?
we are here
+
let node = document.querySelector.bind(document);
const Video = ({src}) => {
return <iframe src={src}/>
}
ReactDOM.render(
<Video src="https://www.youtube.com/embed/u3uh46HiWJ8"/>,
node('.container__mountPoint1')
)
ReactDOM.render(
<Video src="https://www.youtube.com/embed/u3uh46HiWJ8"/>,
node('.container__mountPoint2')
)
const Video = ({src}) => {
return <iframe src={src}/>
}
const componentsToRender = [{
mountPoint: 'container__mountPoint1',
component: Video,
props: {
src: "https://www.youtube.com/embed/u3uh46HiWJ8"
}
},{
mountPoint: 'container__mountPoint2',
component: Video,
props: {
src: "https://www.youtube.com/embed/u3uh46HiWJ8"
}
}]
const reactMount = (Component, selector, props) => {
const mountPoint = node(`.${selector}`);
if (mountPoint){
ReactDOM.render(<Component {...props}/>, mountPoint)
}
}
componentsToRender.forEach(({ mountPoint, component, props }) =>
reactMount(component, mountPoint, props))
1. Functional Programming approach
2. Components can share state even when they are rendered in different mount points
3. Redux is non opinionated and very customizable and extensible
ReacDOM.render(
<Provider store={appStore}>
<Component/>
</Provider>,
document.querySelector('.mount-point')
);
ReacDOM.render(
<Provider store={appStore}>
<Component/>
</Provider>,
document.querySelector('.mount-point')
);
ReacDOM.render(
<Provider store={appStore}>
<Component/>
</Provider>,
document.querySelector('.mount-point')
);
ReacDOM.render(
<Provider store={appStore}>
<Component/>
</Provider>,
document.querySelector('.mount-point')
);
ReacDOM.render(
<Provider store={appStore}>
<Component/>
</Provider>,
document.querySelector('.mount-point')
);
ReacDOM.render(
<Provider store={appStore}>
<Component/>
</Provider>,
document.querySelector('.mount-point')
);
ReacDOM.render(
<Provider store={appStore}>
<Component/>
</Provider>,
document.querySelector('.mount-point')
);
ReacDOM.render(
<Provider store={appStore}>
<Component/>
</Provider>,
document.querySelector('.mount-point')
);
ReacDOM.render(
<Provider store={appStore}>
<Component/>
</Provider>,
document.querySelector('.mount-point')
);
ReacDOM.render(
<Provider store={appStore}>
<Component/>
</Provider>,
document.querySelector('.mount-point')
);
ReacDOM.render(
<Provider store={appStore}>
<Component/>
</Provider>,
document.querySelector('.mount-point')
);
ReacDOM.render(
<Provider store={appStore}>
<Component/>
</Provider>,
document.querySelector('.mount-point')
);
ReacDOM.render(
<Provider store={appStore}>
<Component/>
</Provider>,
document.querySelector('.mount-point')
);
ReacDOM.render(
<Provider store={appStore}>
<Component/>
</Provider>,
document.querySelector('.mount-point')
);
ReacDOM.render(
<Provider store={appStore}>
<Component/>
</Provider>,
document.querySelector('.mount-point')
);
import { Provider } from 'react-redux';
import {
compose,
createStore,
applyMiddleware,
combineReducers
} from 'redux';
const APP_REDUCER_INITIAL_STATE = {};
function appReducer(state = APP_REDUCER_INITIAL_STATE, action){
switch (action.type) {
default:
}
return state;
}
const rootReducer = combineReducers({ appReducer })
const appStore = compose(applyMiddleware(/* My Middlewares */))
(createStore)(rootReducer);
const reduxMount = (Component, selector, props) => {
const mountPoint = node(`.${selector}`);
ReactDOM.render(
<Provider store={appStore}>
<Component {...props}/>
</Provider>, mountPoint)
}
export const VideoContainer = {
component: connect()(Video),
name: 'VideoContainer',
stateKey: 'video',
reducer: videoReducer
}
const rootReducer = combineReducers({
appReducer,
videoReducer
})
const reduxMount = (container, selector, props) => {
const mountPoint = node(`.${selector}`);
const { component: Component } = container;
ReactDOM.render(
<Provider store={appStore}>
<Component {...props}/>
</Provider>, mountPoint)
}
let reducers = {
app: appReducer
}
function addReducer(stateKey, reducer){
reducers = { ...reducers, [stateKey]: reducer }
return appStore.replaceReducer(
combineReducers({ reducers })
)
}
const rootReducer = combineReducers(reducers)
const reduxMount = (container, selector, props) => {
const mountPoint = node(`.${selector}`);
const { component: Component, stateKey, reducer } = container;
addReducer(stateKey, reducer)
ReactDOM.render(
<Provider store={appStore}>
<Component {...props}/>
</Provider>, mountPoint)
}
const APP_REDUCER_INITIAL_STATE = {
reducers: {
app: appReducer
}
};
const appActions = {
REGISTER_REDUCER: 'REGISTER_REDUCER'
}
function appReducer(state = APP_REDUCER_INITIAL_STATE, action){
switch (action.type) {
case appActions.REGISTER_REDUCER:
return registerReducer(state, action.state);
default:
}
return state;
}
function registerReducer(state, newState){
const newReducersList = {
...state.reducers,
...newState
}
return {
...state,
...{
reducers: newReducersList
}
}
}
function addReducer(stateKey, reducer){
const newReducerState = {
[stateKey]: reducer
}
appStore.dispatch({
type: appActions.REGISTER_REDUCER,
state: newReducerState
})
return appStore.replaceReducer(
combineReducers({
...appStore.getState().app.reducers,
...newReducerState
})
)
}
export const VideoContainer = {
component: connect()(Test),
name: 'VideoContainer',
shouldMountPredicate: (state)=>{
return true
},
stateKey: 'video',
reducer: videoReducer
}
const reduxMount = (container, selector, props) => {
const mountPoint = node(`.${selector}`);
const {
component: Component,
stateKey,
reducer,
shouldMountPredicate
} = container;
if (shouldMountPredicate(appStore.getState())){
addReducer(stateKey, reducer)
ReactDOM.render(
<Provider store={appStore}>
<Component {...props}/>
</Provider>, mountPoint
)
}
}