Edit in JSFiddle

const { compose, withState, withHandlers, mapProps } = Recompose
const { omit } = _

const forbidCharacters = forbiddenCharsRegexp =>
  withHandlers({
    onChange: props => event => {
      if (props.onChange) {
        const value = event.target.value
        const cleanValue = value.replace(forbiddenCharsRegexp, '')
        const newEvent = {
          ...event,
          target: { ...event.target, value: cleanValue }
        }
        props.onChange(newEvent)
      }
    }
  })

const formatInputValue = ({ formatValue, parseValue }) =>
  compose(
    withState('inputValue', 'setInputValue', props => formatValue(props.value)),
    withHandlers({
      onChange: props => event => {
        props.setInputValue(event.target.value)
      },
      onBlur: props => event => {
        const parsedValue = parseValue(props.inputValue)
        const formattedValue = formatValue(parsedValue)
        props.setInputValue(formattedValue)
        const newEvent = {
          ...event,
          target: { ...event.target, value: parsedValue }
        }
        if (props.onChange) {
          props.onChange(newEvent)
        }
        if (props.onBlur) {
          props.onBlur(newEvent)
        }
      }
    }),
    mapProps(({ inputValue, ...otherProps }) => ({
      ...omit(otherProps, ['inputValue', 'setInputValue']),
      value: inputValue
    }))
  )

const BaseInput = props => <input {...props} />

const PhoneNumberInput = compose(
  formatInputValue({
    formatValue: value => {
      return value.replace(/^(\d{3})(\d{3})(\d{4})$/, '($1) $2-$3')
    },
    parseValue: formattedValue => {
      return formattedValue.replace(/[^\d]/g, '').slice(0, 10)
    }
  }),
  forbidCharacters(/[^\d\s\-()]/g)
)(BaseInput)

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = { phoneNumber: '' }
  }
  onChange = event => {
    this.setState({ phoneNumber: event.target.value })
  }
  render() {
    return (
      <div>
        <PhoneNumberInput
          value={this.state.phoneNumber}
          onChange={this.onChange}
          style={{ padding: 5, fontSize: 'large' }}
        />
        <br />
        <code>{JSON.stringify(this.state)}</code>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('container'))