Skip to content

Commit

Permalink
Remove deprecated lifecycle methods and reduce rerendering
Browse files Browse the repository at this point in the history
  • Loading branch information
Vlad committed Jan 24, 2020
1 parent d4a4841 commit 5b1638e
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 38 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@shoutem/theme",
"version": "0.11.1",
"version": "0.11.4",
"main": "index.js",
"description": "Style your components in one place.",
"dependencies": {
Expand All @@ -15,7 +15,7 @@
},
"devDependencies": {
"babel": "^6.3.26",
"babel-preset-react-native": "^1.9.0",
"babel-preset-react-native": "^5.0.1",
"chai": "^3.4.1",
"deep-freeze": "0.0.1",
"enzyme": "^2.0.0-rc1",
Expand Down
26 changes: 11 additions & 15 deletions src/StyleProvider.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { Children } from 'react';
import React, { PureComponent, Children } from 'react';
import PropTypes from 'prop-types';
import Theme, { ThemeShape } from './Theme';

/**
* Provides a theme to child components trough context.
*/
export default class StyleProvider extends React.Component {
export default class StyleProvider extends PureComponent {
static propTypes = {
children: PropTypes.element.isRequired,
style: PropTypes.object,
Expand All @@ -19,10 +19,18 @@ export default class StyleProvider extends React.Component {
theme: ThemeShape.isRequired,
};

static getDerivedStateFromProps(props, state) {
return props.style === state.style ? state : {
style: props.style,
theme: new Theme(props.style),
};
}

constructor(props, context) {
super(props, context);

this.state = {
theme: this.createTheme(props),
theme: new Theme(props.style),
};
}

Expand All @@ -32,18 +40,6 @@ export default class StyleProvider extends React.Component {
};
}

componentWillReceiveProps(nextProps) {
if (nextProps.style !== this.props.style) {
this.setState({
theme: this.createTheme(nextProps),
});
}
}

createTheme(props) {
return new Theme(props.style);
}

render() {
const { children } = this.props;

Expand Down
48 changes: 27 additions & 21 deletions src/connectStyle.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import hoistStatics from 'hoist-non-react-statics';
import * as _ from 'lodash';
import normalizeStyle from './StyleNormalizer/normalizeStyle';
import _ from 'lodash';

import Theme, { ThemeShape } from './Theme';
import normalizeStyle from './StyleNormalizer/normalizeStyle';
import { resolveComponentStyle } from './resolveComponentStyle';
import Theme, { ThemeShape } from './Theme';

// TODO - remove withRef warning in next version

Expand Down Expand Up @@ -46,7 +46,12 @@ function getTheme(context) {
* @returns {StyledComponent} The new component that will handle
* the styling of the wrapped component.
*/
export default (componentStyleName, componentStyle = {}, mapPropsToStyleNames, options = {}) => {
export default function connectStyle(
componentStyleName,
componentStyle = {},
mapPropsToStyleNames,
options = {}
) {
function getComponentDisplayName(WrappedComponent) {
return WrappedComponent.displayName || WrappedComponent.name || 'Component';
}
Expand Down Expand Up @@ -75,7 +80,7 @@ export default (componentStyleName, componentStyle = {}, mapPropsToStyleNames, o
);
}

class StyledComponent extends React.PureComponent {
class StyledComponent extends PureComponent {
static contextTypes = {
theme: ThemeShape,
// The style inherited from the parent
Expand Down Expand Up @@ -112,8 +117,10 @@ export default (componentStyleName, componentStyle = {}, mapPropsToStyleNames, o

constructor(props, context) {
super(props, context);

const styleNames = this.resolveStyleNames(props);
const resolvedStyle = this.resolveStyle(context, props, styleNames);

this.setWrappedInstance = this.setWrappedInstance.bind(this);
this.transformProps = this.transformProps.bind(this);

Expand All @@ -137,10 +144,11 @@ export default (componentStyleName, componentStyle = {}, mapPropsToStyleNames, o
};
}

componentWillReceiveProps(nextProps, nextContext) {
const styleNames = this.resolveStyleNames(nextProps);
if (this.shouldRebuildStyle(nextProps, nextContext, styleNames)) {
const resolvedStyle = this.resolveStyle(nextContext, nextProps, styleNames);
componentDidUpdate(prevProps) {
const styleNames = this.resolveStyleNames(this.props);

if (this.shouldRebuildStyle(prevProps, styleNames)) {
const resolvedStyle = this.resolveStyle(this.context, this.props, styleNames);

this.setState({
style: resolvedStyle.componentStyle,
Expand All @@ -152,7 +160,7 @@ export default (componentStyleName, componentStyle = {}, mapPropsToStyleNames, o

setNativeProps(nativeProps) {
if (!this.isRefDefined()) {
console.warn('setNativeProps can\'nt be used on stateless components');
console.warn('setNativeProps can\'t be used on stateless components');
return;
}
if (this.wrappedInstance.setNativeProps) {
Expand All @@ -164,19 +172,17 @@ export default (componentStyleName, componentStyle = {}, mapPropsToStyleNames, o
this.wrappedInstance = component;
}

hasStyleNameChanged(nextProps, styleNames) {
return mapPropsToStyleNames && this.props !== nextProps &&
// Even though props did change here,
// it doesn't necessary means changed props are those which affect styleName
hasStyleNameChanged(prevProps, styleNames) {
return mapPropsToStyleNames && this.props !== prevProps &&
// Even though props did change here, it doesn't necessarily mean
// props that affect styleName have changed
!_.isEqual(this.state.styleNames, styleNames);
}

shouldRebuildStyle(nextProps, nextContext, styleNames) {
return (nextProps.style !== this.props.style) ||
(nextProps.styleName !== this.props.styleName) ||
(nextContext.theme !== this.context.theme) ||
(nextContext.parentStyle !== this.context.parentStyle) ||
(this.hasStyleNameChanged(nextProps, styleNames));
shouldRebuildStyle(prevProps, styleNames) {
return (prevProps.style !== this.props.style) ||
(prevProps.styleName !== this.props.styleName) ||
(this.hasStyleNameChanged(prevProps, styleNames));
}

resolveStyleNames(props) {
Expand Down

0 comments on commit 5b1638e

Please sign in to comment.