Skip to content

Instantly share code, notes, and snippets.

@fmal
Created December 20, 2018 20:47
Show Gist options
  • Save fmal/68d09420d3550df7b1f0d7f8a6e92219 to your computer and use it in GitHub Desktop.
Save fmal/68d09420d3550df7b1f0d7f8a6e92219 to your computer and use it in GitHub Desktop.
import { Component } from 'react';
import PropTypes from 'prop-types';
export default class ControlledComponent extends Component {
isControlledProp = key => Object.prototype.hasOwnProperty.call(this.props, key);
getControlledState = (state = this.state) => {
return Object.keys(state).reduce((combinedState, key) => {
combinedState[key] = this.isControlledProp(key)
? this.props[key]
: state[key];
return combinedState;
}, {});
};
setControlledState = (stateToSet, callback = Function.prototype) => {
const { onStateChange } = this.props;
if (onStateChange) {
let allChanges;
this.setState(
state => {
const combinedState = this.getControlledState(state);
stateToSet =
typeof stateToSet === 'function' ? stateToSet(combinedState) : stateToSet;
allChanges = stateToSet;
const nonControlledChanges = Object.keys(stateToSet).reduce(
(internalChanges, key) => {
if (!this.isControlledProp(key)) {
internalChanges[key] = stateToSet[key];
}
return internalChanges;
}
);
return Object.keys(nonControlledChanges).length
? nonControlledChanges
: null;
},
() => {
this.props.onStateChange(allChanges);
callback();
}
);
} else {
this.setState(changes, callback);
}
};
}
ControlledComponent.propTypes = {
onStateChange: PropTypes.func
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment