Skip to content

Instantly share code, notes, and snippets.

@styfle
Last active April 17, 2018 17:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save styfle/cce13d20510e131a591b6e61072e4396 to your computer and use it in GitHub Desktop.
Save styfle/cce13d20510e131a591b6e61072e4396 to your computer and use it in GitHub Desktop.
InputNumber.tsx example for componentWillReceiveProps
interface Props {
value: number;
onChange: (value: number) => void;
widthPx?: number;
inline?: boolean;
disabled?: boolean;
}
interface State {
valueAsString: string;
}
export class InputNumber extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { valueAsString: isEmpty(props.value) ? '' : props.value.toString() };
}
handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const valueAsString = e.target.value;
const valueAsNumber = toFloat(valueAsString);
this.setState({ valueAsString: valueAsString }, () => {
this.props.onChange(valueAsNumber);
});
}
componentWillReceiveProps(nextProps: Props) {
if (nextProps.value !== toFloat(this.state.valueAsString)) {
this.setState({ valueAsString: isEmpty(nextProps.value) ? '' : nextProps.value.toString() });
}
}
render() {
const { widthPx, inline, disabled } = this.props;
const style: React.CSSProperties = { width: widthPx || '100%', display: inline ? 'inline-block' : 'block' };
return (<div style={style}>
<input type="text" value={this.state.valueAsString} onChange={this.handleChange} style={style} disabled={disabled} />
</div>);
}
}
function isEmpty(val: number): boolean {
const t = typeof val;
return t === 'undefined' || val === null || (t === 'number' && isNaN(val));
}
function toFloat(s: string) {
return parseFloat(s.replace(/,/g, ''));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment