Skip to content

Commit

Permalink
Merge pull request #1718 from oliviertassinari/fix-pure-context
Browse files Browse the repository at this point in the history
[PureRender] fix rerender if the context change
  • Loading branch information
shaurya947 committed Sep 24, 2015
2 parents fd69f53 + d0e4ce6 commit 1963003
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 53 deletions.
20 changes: 11 additions & 9 deletions src/buttons/flat-button-label.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
const React = require('react/addons');
const PureRenderMixin = React.addons.PureRenderMixin;
const ContextPure = require('../mixins/context-pure');
const Styles = require('../utils/styles');
const DefaultRawTheme = require('../styles/raw-themes/light-raw-theme');
const ThemeManager = require('../styles/theme-manager');

const FlatButtonLabel = React.createClass({

mixins: [PureRenderMixin],
mixins: [
ContextPure,
],

contextTypes: {
muiTheme: React.PropTypes.object,
Expand Down Expand Up @@ -41,12 +43,12 @@ const FlatButtonLabel = React.createClass({
this.setState({muiTheme: newMuiTheme});
},

getRelevantContextKeys() {
const theme = this.state.muiTheme;

return {
spacingDesktopGutterLess: theme.rawTheme.spacing.desktopGutterLess,
};
static: {
getRelevantContextKeys(muiTheme) {
return {
spacingDesktopGutterLess: muiTheme.rawTheme.spacing.desktopGutterLess,
};
},
},

render: function() {
Expand All @@ -55,7 +57,7 @@ const FlatButtonLabel = React.createClass({
style,
} = this.props;

const contextKeys = this.getRelevantContextKeys();
const contextKeys = this.getRelevantContextKeys(this.state.muiTheme);

const mergedRootStyles = Styles.mergeAndPrefix({
position: 'relative',
Expand Down
25 changes: 17 additions & 8 deletions src/card/card-expandable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ const IconButton = require('../icon-button');
const StylePropable = require('../mixins/style-propable');
const DefaultRawTheme = require('../styles/raw-themes/light-raw-theme');
const ThemeManager = require('../styles/theme-manager');
const ContextPure = require('../mixins/context-pure');

const CardExpandable = React.createClass({
mixins: [StylePropable],
mixins: [
StylePropable,
ContextPure,
],

getStyles() {
const contextKeys = this.getRelevantContextKeys();
const contextKeys = this.getRelevantContextKeys(this.state.muiTheme);

const directionStyle = contextKeys.isRtl ? {
left: 4,
Expand Down Expand Up @@ -49,12 +53,17 @@ const CardExpandable = React.createClass({
};
},

getRelevantContextKeys() {
const theme = this.state.muiTheme;

return {
isRtl: theme.isRtl,
};
static: {
getRelevantContextKeys(muiTheme) {
return {
isRtl: muiTheme.isRtl,
};
},
getChildrenClasses() {
return [
IconButton,
];
},
},

getInitialState() {
Expand Down
11 changes: 5 additions & 6 deletions src/mixins/context-pure.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ function relevantContextKeysEqual(classObject, currentContext, nextContext) {
if (classObject.getRelevantContextKeys) {
const currentContextKeys = classObject.getRelevantContextKeys(currentContext);
const nextContextKeys = classObject.getRelevantContextKeys(nextContext);

if (!shallowEqual(currentContextKeys, nextContextKeys)) {
return false;
}
Expand All @@ -30,16 +31,14 @@ module.exports = {

//Don't update if state, prop, and context are equal
shouldComponentUpdate(nextProps, nextState, nextContext) {

const staticTheme = (
this.context.muiTheme &&
this.context.muiTheme.static
);
const staticTheme = this.context.muiTheme && this.context.muiTheme.static;
const isExactlyOneThemeUndefined = (!this.context.muiTheme && nextContext.muiTheme) || (this.context.muiTheme && !nextContext.muiTheme);

return (
!shallowEqual(this.props, nextProps) ||
!shallowEqual(this.state, nextState) ||
(!staticTheme && !relevantContextKeysEqual(this.constructor, this.context, nextContext))
isExactlyOneThemeUndefined ||
(!staticTheme && !relevantContextKeysEqual(this.constructor, this.context.muiTheme, nextContext.muiTheme))
);
},

Expand Down
74 changes: 49 additions & 25 deletions src/text-field.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const UniqueId = require('./utils/unique-id');
const EnhancedTextarea = require('./enhanced-textarea');
const DefaultRawTheme = require('./styles/raw-themes/light-raw-theme');
const ThemeManager = require('./styles/theme-manager');
const ContextPure = require('./mixins/context-pure');

/**
* Check if a value is valid to be displayed inside an input.
Expand All @@ -19,7 +20,10 @@ function isValid(value) {

const TextField = React.createClass({

mixins: [StylePropable],
mixins: [
ContextPure,
StylePropable,
],

contextTypes: {
muiTheme: React.PropTypes.object,
Expand Down Expand Up @@ -69,12 +73,27 @@ const TextField = React.createClass({
};
},

getRelevantContextKeys() {
const theme = this.state.muiTheme;

return {
isRtl: theme.isRtl,
};
statics: {
getRelevantContextKeys(muiTheme) {
const textFieldTheme = this.state.muiTheme.textField

return {
floatingLabelColor: textFieldTheme.floatingLabelColor,
focusColor: textFieldTheme.focusColor,
borderColor: textFieldTheme.borderColor,
textColor: textFieldTheme.textColor,
disabledTextColor: textFieldTheme.disabledTextColor,
backgroundColor: textFieldTheme.backgroundColor,
hintColor: textFieldTheme.hintColor,
errorColor: textFieldTheme.errorColor,
isRtl: muiTheme.isRtl,
};
},
getChildrenClasses() {
return [
EnhancedTextarea,
];
},
},

getInitialState() {
Expand All @@ -88,10 +107,6 @@ const TextField = React.createClass({
};
},

getTheme() {
return this.state.muiTheme.textField;
},

componentDidMount() {
this._uniqueId = UniqueId.generate();
},
Expand Down Expand Up @@ -123,9 +138,18 @@ const TextField = React.createClass({
},

getStyles() {
let props = this.props;
let theme = this.getTheme();
const contextKeys = this.getRelevantContextKeys();
const props = this.props;
const {
floatingLabelColor,
focusColor,
borderColor,
textColor,
disabledTextColor,
backgroundColor,
hintColor,
errorColor,
isRtl,
} = this.getRelevantContextKeys(this.state.muiTheme);

let styles = {
root: {
Expand All @@ -143,14 +167,14 @@ const TextField = React.createClass({
bottom: 5,
fontSize: 12,
lineHeight: '12px',
color: theme.errorColor,
color: errorColor,
transition: Transitions.easeOut(),
},
hint: {
position: 'absolute',
lineHeight: '22px',
opacity: 1,
color: theme.hintColor,
color: hintColor,
transition: Transitions.easeOut(),
bottom: 12,
},
Expand All @@ -162,13 +186,13 @@ const TextField = React.createClass({
height: '100%',
border: 'none',
outline: 'none',
backgroundColor: theme.backgroundColor,
color: props.disabled ? theme.disabledTextColor : theme.textColor,
backgroundColor: backgroundColor,
color: props.disabled ? disabledTextColor : textColor,
font: 'inherit',
},
underline: {
border: 'none',
borderBottom: 'solid 1px ' + theme.borderColor,
borderBottom: 'solid 1px ' + borderColor,
position: 'absolute',
width: '100%',
bottom: 8,
Expand All @@ -184,11 +208,11 @@ const TextField = React.createClass({
userSelect: 'none',
cursor: 'default',
bottom: 8,
borderBottom: 'dotted 2px ' + theme.disabledTextColor,
borderBottom: 'dotted 2px ' + disabledTextColor,
},
underlineFocus: {
borderBottom: 'solid 2px',
borderColor: theme.focusColor,
borderColor: focusColor,
transform: 'scaleX(0)',
transition: Transitions.easeOut(),
},
Expand All @@ -204,7 +228,7 @@ const TextField = React.createClass({
bottom: 'none',
opacity: 1,
transform: 'scale(1) translate3d(0, 0, 0)',
transformOrigin: contextKeys.isRtl ? 'right top' : 'left top',
transformOrigin: isRtl ? 'right top' : 'left top',
});

styles.textarea = this.mergeStyles(styles.input, {
Expand All @@ -217,13 +241,13 @@ const TextField = React.createClass({
styles.focusUnderline = this.mergeStyles(styles.underline, styles.underlineFocus, props.underlineFocusStyle);

if (this.state.isFocused) {
styles.floatingLabel.color = theme.focusColor;
styles.floatingLabel.color = focusColor;
styles.floatingLabel.transform = 'perspective(1px) scale(0.75) translate3d(2px, -28px, 0)';
styles.focusUnderline.transform = 'scaleX(1)';
}

if (this.state.hasValue) {
styles.floatingLabel.color = ColorManipulator.fade(props.disabled ? theme.disabledTextColor : theme.floatingLabelColor, 0.5);
styles.floatingLabel.color = ColorManipulator.fade(props.disabled ? disabledTextColor : floatingLabelColor, 0.5);
styles.floatingLabel.transform = 'perspective(1px) scale(0.75) translate3d(2px, -28px, 0)';
styles.hint.opacity = 0;
}
Expand Down Expand Up @@ -311,7 +335,7 @@ const TextField = React.createClass({
<EnhancedTextarea
{...other}
{...inputProps}
rows={rows}
rows={rows}
onHeightChange={this._handleTextAreaHeightChange}
textareaStyle={this.mergeAndPrefix(styles.textarea)} />
) : (
Expand Down
9 changes: 4 additions & 5 deletions test/mixin-context-pure-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ const GrandChildComponent = React.createClass({
},

statics: {
getRelevantContextKeys(context) {
getRelevantContextKeys(muiTheme) {
return {
grandChildThemeProp: context.muiTheme.grandChildThemeProp,
grandChildThemeProp: muiTheme.grandChildThemeProp,
}
},
},
Expand Down Expand Up @@ -47,9 +47,9 @@ const ChildComponent = React.createClass({
},

statics: {
getRelevantContextKeys(context) {
getRelevantContextKeys(muiTheme) {
return {
childThemeProp: context.muiTheme.childThemeProp,
childThemeProp: muiTheme.childThemeProp,
}
},
getChildrenClasses() {
Expand Down Expand Up @@ -159,7 +159,6 @@ const ParentComponent = React.createClass({
describe('Mixin-ContextPure', () => {
let parentElement;


describe('when muiTheme.static is false', () => {

beforeEach(() => {
Expand Down

0 comments on commit 1963003

Please sign in to comment.