import React, { ChangeEvent, FocusEvent } from 'react'; type Props = React.HTMLAttributes & { value: string; onChange: (e: ChangeEvent) => void; onFocus: (e: FocusEvent) => void; onBlur: (e: FocusEvent) => void; } type State = { isFocused: boolean; currentValue: string; } class Input extends React.Component { static defaultProps: Partial = { onChange: () => {}, onFocus: () => {}, onBlur: () => {} }; state: State = { isFocused: false, currentValue: this.props.value }; static getDerivedStateFromProps(nextProps: Props, prevState: State) { // This lifecycle method does not have access to 'this', // so you cannot directly compare with 'this.state'. // Instead, it receives the next props and previous state: if (!prevState.isFocused) { return { currentValue: nextProps.value }; } return null; // Return null to indicate no change to state. } handleChange = (e: ChangeEvent) => { this.setState({ currentValue: e.target.value }); this.props.onChange(e); }; handleFocus = (e: FocusEvent) => { this.setState({ isFocused: true }); this.props.onFocus(e); }; handleBlur = (e: FocusEvent) => { this.setState({ isFocused: false }); this.props.onBlur(e); }; render() { // Destructuring to avoid passing internal methods or state as props to the input element const { value, onChange, onFocus, onBlur, ...rest } = this.props; return ( ); } } export default Input;