2017-08-17 15 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> 
     ); 
    } 
} 
相关问题