├── README.md └── index.js /README.md: -------------------------------------------------------------------------------- 1 | # react-input 2 | See https://github.com/facebook/react/issues/3926 3 | 4 | ## Usage 5 | 6 | 7 | ```shell 8 | npm install lodash --save # for debounce util 9 | ``` 10 | 11 | ```js 12 | import React, { Component } from 'react' 13 | 14 | import Input from './index' 15 | 16 | class New extends Component { 17 | constructor(props) { 18 | super(props) 19 | 20 | this.state = { 21 | value: '' 22 | } 23 | 24 | this.handleChange = this.handleChange.bind(this) 25 | } 26 | 27 | 28 | handleChange(value) { 29 | this.setState({value}) 30 | } 31 | 32 | render() { 33 | return ( 34 |
35 | You type: {this.state.value} 36 |
37 | { // refc for ref 40 | this._input = c // you can access input DOM node with this._input 41 | }} 42 | onChange={value => { 43 | this.handleChange(value) 44 | }} 45 | /> 46 |
47 | ) 48 | } 49 | } 50 | ``` 51 | 52 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import debounce from 'lodash/debounce' 3 | 4 | class Input extends Component { 5 | constructor(props){ 6 | super(props) 7 | 8 | this.state={ 9 | value: props.value, 10 | } 11 | 12 | this.onComposition = false 13 | this.handleComposition = this.handleComposition.bind(this) 14 | this.handleChange = this.handleChange.bind(this) 15 | 16 | this.propsHandleChange = ( 17 | props.debounce ? 18 | debounce(props.onChange, props.debounce) : 19 | props.onChange 20 | ) 21 | } 22 | 23 | componentWillReceiveProps(nextProps) { 24 | if (nextProps.value !== this.props.value) { 25 | this.setState({value: nextProps.value}) 26 | } 27 | } 28 | 29 | handleComposition(e) { 30 | if (e.type === 'compositionend') { 31 | this.onComposition = false 32 | } else { 33 | this.onComposition = true 34 | } 35 | } 36 | 37 | handleChange(value) { 38 | this.setState({ 39 | value: value, 40 | }, () => { 41 | if (this.onComposition) return 42 | this.propsHandleChange(value) 43 | }) 44 | } 45 | 46 | render() { 47 | const { // eslint-disable-next-line 48 | tagName, debounce, refc, 49 | ...other, 50 | } = this.props 51 | const Tag = tagName 52 | return ( 53 | { 59 | refc(c) 60 | return c 61 | }} 62 | onChange={(e) => { 63 | this.handleChange(e.target.value) 64 | }} 65 | value={this.state.value} 66 | /> 67 | ) 68 | } 69 | } 70 | 71 | Input.defaultProps = { 72 | tagName: 'input', 73 | type: 'text', 74 | value: '', 75 | onChange: function(value){}, 76 | refc: function(c) {}, 77 | } 78 | 79 | export default Input --------------------------------------------------------------------------------