2017-08-17 77 views
1

我有一個受控組件與代表日期值的input字段。由於這一天值可以有1-2位數字,例如必須刪除12才能輸入21. 由於onChange react-event的行爲類似於DOM事件,因此我只能刪除或輸入一位數字並且事件被觸發,因此整個模型在設置日期過早時會更新我刪除了一個數字之後就是一個。受控組件輸入字段onChange行爲

<input 
    name={name} 
    type="number" 
    value={value} 
    onChange={(e) => { onChange(e.target.value) } } 
/> 

由於defaultValue change does not re-render input我可以與不受控制部件輸入與onBlur事件處理這個問題。使用key確保,一個新的渲染髮生,當模型通過其他方式改變:

<input 
    name={name} 
    type="number" 
    defaultValue={value} 
    key={value} 
    onBlur={(e) => { onChange(e.target.value); }} 
/> 

但說實話,這種感覺就像一個黑客攻擊。你如何專業解決這種情況?我忽略了一些更簡單的東西嗎?在更新模型之前是否使用超時函數(因此等待完整的用戶輸入)又稱去抖?

回答

2

爲什麼不能同時使用onChangeonBlur

class NumberChooser extends React.Component{ 
    constructor(props){ 
     super(props); 
     this.state = { 
      fieldValue: props.value, 
      time: '' 
     } 
    } 
    onChange(e){ 
     this.setState({fieldValue: e.target.value}); 
    } 
    render(){ 
     return ( 
       <input 
        name={this.props.name} 
        type="number" 
        value={this.state.fieldValue} 
        //key={value} not sure what do with this 
        onChange={this.onChange} 
        onBlur={(e) => this.props.onChange(e.target.value)} 
       /> 
     ); 
    } 
} 
export default NumberChooser; 
+0

我可以但這不解決當我刪除「22」的第一個數字以將其更改爲「31」左右時立即重新渲染的問題。正如我所說,我可能會使用去抖動留在現場並完成輸入。 –

+1

據我所知,當日期爲「2」且問題不正確時,問題重新渲染。但是在這個變體中,每個字符被刪除後,組件會重新渲染,但是這隻會反映在輸入值和state.time中,直到onBlur沒有被觸發爲止。 – Andrew

+0

是的,我單獨嘗試了'onBlur',但是當我刪除一個字符(它甚至沒有更新模型)時,它不會重新渲染字段。當我同時使用'onBlur'和'onChange'時,行爲與單獨使用'onChange'相同。我會堅持使用'key'來控制不受控制的變體,以強制重新渲染,這似乎是個訣竅,但感覺像上面提到的那樣。 –

0

感謝Andrew的意見,它告訴我,使用本地狀態可以解決我的問題。現在該組件是一個類而不是功能組件了。仍然覺得有點尷尬存儲一個字段的顯示值本地只是爲了能夠使用onChange沒有中間編輯字段更新來自主要狀態。但它似乎是這樣的,如果一個人想要使用具有單一事實來源的受控組件,我只會將本地狀態視爲UI狀態;-)

export default class NumberChooser extends React.Component { 
    static propTypes = { 
     name:  PropTypes.string.isRequired, 
     value:  PropTypes.number.isRequired, 
     onChange: PropTypes.func.isRequired, 
    }; 
    constructor(props) { 
     super(props); 
     this.state = { value: this.props.value }; 
    } 
    componentWillReceiveProps(nextProps) { 
     if (nextProps.value !== this.props.value) { 
      this.setState({ value: nextProps.value }); 
     } 
    } 
    render() { 
     return (
      <div className="col" name={`NumberChooser_${this.props.name}`} style={ isDebug ? debug.borderStyle : {} } >  
       <IncButton 
        onButtonClicked={() => this.props.onChange(this.state.value+1)} 
       /> 
       <input 
        name={this.props.name} 
        type="number" 
        value={this.state.value} 
        onChange={(e) => { this.setState({ value: e.target.value }); } } 
        onBlur={(e) => { this.props.onChange(e.target.value); }} 
       /> 
       <DecButton 
        onButtonClicked={() => this.props.onChange(this.state.value-1)} 
       /> 
      </div> 
     ); 
    } 
} 
相關問題