Skip to content

Instantly share code, notes, and snippets.

@alexeychikk
Last active September 21, 2016 10:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexeychikk/add4db3397df9feb2a0daf155376a5a8 to your computer and use it in GitHub Desktop.
Save alexeychikk/add4db3397df9feb2a0daf155376a5a8 to your computer and use it in GitHub Desktop.
Simple workaround to redux shouldComponentUpdate disregards react context
/**
* Usage
*
import React, { Component, PropTypes } from 'react';
import ReduxContextFix from '../util/reduxContextFix';
class ScreenSizeAware extends Component {
static childContextTypes = {
screenData: PropTypes.object
};
getChildContext() {
return {
screenData: this.state.screenData
};
}
constructor(props) {
//...
ReduxContextFix.register(this);
}
_handleWindowResize() {
let width = window.innerWidth;
let newState = {
screenData: { width, small: width <= 768 }
};
this.setState(newState);
ReduxContextFix.notify(newState)
}
//...
};
class View extends Component {
static contextTypes = {
screenData: PropTypes.shape({
small: PropTypes.bool,
width: PropTypes.number
})
};
constructor(props) {
//...
ReduxContextFix.connect(this);
}
}
*
*/
class ReduxContextFix {
constructor() {
if (ReduxContextFix.instance) return ReduxContextFix.instance;
ReduxContextFix.instance = this;
this.contexts = {};
this.connectedComponets = {};
}
connect(component) {
let componentClass = Object.getPrototypeOf(component).constructor;
for (let contextName in componentClass.contextTypes) {
if (this.contexts[contextName]) {
this.connectedComponets[contextName] = this.connectedComponets[contextName] || [];
this.connectedComponets[contextName].push(component);
let cwum = component.componentWillUnmount;
component.componentWillUnmount = () => {
cwum && cwum.call(component);
this.connectedComponets[contextName] = this.connectedComponets[contextName]
.filter(c => c !== component);
};
}
}
}
register(component) {
if (!component.getChildContext) throw new Error('Component must provide context!');
let context = component.getChildContext();
for (let cname in context) {
this.contexts[cname] = true;
}
}
notify(newState) {
for (let key in newState) {
if (this.contexts[key]) {
let context = newState[key];
let connectedComponents = this.connectedComponets[key];
if (!connectedComponents) continue;
for (let i = 0, length = connectedComponents.length; i < length; i++) {
let cc = connectedComponents[i];
cc.context[key] = context;
cc.forceUpdate();
}
}
}
}
}
export default (new ReduxContextFix());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment