Skip to content

Instantly share code, notes, and snippets.

@rchanou
Last active January 4, 2021 02:35
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rchanou/0a5c4173803a0d654f4c986d696a5c7f to your computer and use it in GitHub Desktop.
Save rchanou/0a5c4173803a0d654f4c986d696a5c7f to your computer and use it in GitHub Desktop.
Semi-Controlled Input
export default class Input extends React.Component {
static defaultProps = {
onChange() {},
onFocus() {},
onBlur() {}
};
constructor(props) {
super();
this.state = {
isFocused: false,
currentValue: props.value
};
}
handleChange = (e, ...rest) => {
this.setState({ currentValue: e.target.value });
this.props.onChange(e, ...rest);
};
handleFocus = (...args) => {
this.setState({ isFocused: true });
this.props.onFocus(...args);
};
handleBlur = (...args) => {
this.setState({ isFocused: false });
this.props.onBlur(...args);
};
componentWillReceiveProps(nextProps) {
if (!this.state.isFocused) {
this.setState({ currentValue: nextProps.value });
}
}
render() {
return (
<input
{...this.props}
onChange={this.handleChange}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
value={this.state.currentValue}
/>
);
}
}
@rchanou
Copy link
Author

rchanou commented Apr 1, 2017

Use this just like a regular input.
The only difference is that when it's focused, it won't take outside values.
In other words, it's "uncontrolled" when focused, "controlled" when not.
This is commonly the desired behavior for good UX.

@aearly
Copy link

aearly commented Aug 28, 2017

This is a very useful little component! Would you mind publishing this on npm (and giving it a license)?

@rchanou
Copy link
Author

rchanou commented Sep 12, 2017

@aerly Sure, I'll try to get around to it. Love icepick BTW!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment