Reactjs 如何允许在不更新React中的道具的情况下进行输入更新?

Reactjs 如何允许在不更新React中的道具的情况下进行输入更新?,reactjs,Reactjs,我希望允许用户在输入字段中输入更改,而无需将更改传播到父项。每当我不想传播时,我都会退出onChange函数。然而,这似乎撤销了我键入的字符 这里是一个用例。我有一个数字字段。当输入一个数字时,我想在父级上触发onChange,但忽略“.”和“,”s(formatters.staticToFloat删除它们) export default class NumberField扩展React.Component{ 渲染(){ var props=this.props; var format=pro

我希望允许用户在输入字段中输入更改,而无需将更改传播到父项。每当我不想传播时,我都会退出
onChange
函数。然而,这似乎撤销了我键入的字符

这里是一个用例。我有一个数字字段。当输入一个数字时,我想在父级上触发
onChange
,但忽略“.”和“,”s(
formatters.staticToFloat
删除它们)

export default class NumberField扩展React.Component{
渲染(){
var props=this.props;
var format=props.formatter | | formatters.number;
返回(
{props.inputLabel}
);
}
onChange(e){
var numValue=formatters.stringToFloat(即target.value);
//他们添加了一个。或者,我们不传播变化
if(this.props.value===numValue){
回来
}
if(this.props.onChange){
这个。道具。改变({
值:numValue,
valid:validation.isValid(numValue,this.props.validation)
});
}
}

};到目前为止,我想到的最好的方法是维护一个单独的
formattedValue
状态,该状态仅在我想要覆盖默认格式时设置。它是有效的,但似乎是一个超级肮脏的解决方案

export default class NumberField扩展React.Component{
构造函数(){
超级();
此.state={
formattedValue:null
};
}
渲染(){
var props=this.props;
var state=this.state;
var format=props.formatter | | formatters.number;
var inputValue=state.formattedValue | |(
!\是否未定义(道具值)?
格式(props.value):
无效的
);
返回(
{props.inputLabel}
);
}
onChange(e){
var numValue=formatters.stringToFloat(即target.value);
//他们添加了一个。或者,我们不传播变化
if(this.props.value===numValue){
这是我的国家({
formattedValue:e.target.value
});
}否则{
这是我的国家({
formattedValue:null
});
}
if(this.props.onChange){
这个。道具。改变({
值:numValue,
valid:validation.isValid(numValue,this.props.validation)
});
}
}

};听起来像是使用state在组件内部存储格式化值,并使用setState的特殊变量和回调

  • 所有用户输入(包括.和,)都处于状态,并在输入字段中呈现给用户
  • 只有当格式正确时,才会调用父级
    onChange()
父级实际上可能会执行由
onChange()
调用触发的重新渲染。因此,我们需要确保最后输入的字符在状态中更新,并且只有在更新之后才会调用父级的
onChange()

您的组件如下所示:

export default class NumberField extends React.Component {
  constructor (props) {
    super(props);
    this.state = {
      value: !_.isUndefined(props.value) ? 
        props.formatter ? props.formatter(props.value).toString() : formatters.number(props.value).toString() 
        : null;
    };
  }

  render () {
    var props = this.props;
    var state = this.state;
    return (
      <div>
        <label>{props.inputLabel}</label>
        <input
          type="text"
          name={props.name}
          onChange={this.onChange.bind(this)}
          value={state.value}
        />
      </div>
    );
  }

  onChange (e) {
    var numValue = formatters.stringToFloat(e.target.value);
    // if numValue is different from current state
    // then it must be an OK update, 
    // so we update state AND call parent if function exists
    if (numValue.toString() != this.state.value) {
      this.setState({
        value: numValue
      },
      this.callParent // here is the magic: we pass a callback, to be  called after state update and after re-render
      );
    } else {
     // otherwise we only update state (to display invalid character)
      this.setState({
        value: numValue
      });
    }
  }

  callParent() {
    // state is updated and component has re-rendered when this is called
    // so we can use state.value to inform parent
    if (this.props.onChange) {
      this.props.onChange({
        value: this.state.value,
        valid: validation.isValid(this.state.value, this.props.validation)
      });
    }    
  }
};
export default class NumberField扩展React.Component{
建造师(道具){
超级(道具);
此.state={
值:!\是否未定义(道具值)?
props.formatter?props.formatter(props.value).toString():formatters.number(props.value).toString()
:null;
};
}
渲染(){
var props=this.props;
var state=this.state;
返回(
{props.inputLabel}
);
}
onChange(e){
var numValue=formatters.stringToFloat(即target.value);
//如果numValue与当前状态不同
//那么它必须是一个OK更新,
//所以,如果函数存在,我们更新状态并调用父函数
if(numValue.toString()!=this.state.value){
这是我的国家({
值:numValue
},
this.callParent//神奇之处在于:我们传递一个回调,在状态更新和重新渲染后调用
);
}否则{
//否则我们只更新状态(以显示无效字符)
这是我的国家({
值:numValue
});
}
}
callParent(){
//调用时,状态将更新,并且组件已重新呈现
//所以我们可以使用state.value通知家长
if(this.props.onChange){
这个。道具。改变({
value:this.state.value,
valid:validation.isValid(this.state.value、this.props.validation)
});
}    
}
};
这可能有点过分:您保留了一个状态(格式化值),还可以与父级通信。如果您的父级总是传递新转发的输入,那么您可以使组件更简单: 没有状态,只是基于道具重新渲染


只有当输入字段中呈现给用户的值可能与您与家长的通信内容不同时,才真正需要状态。

如果用户键入“123”,该怎么办?是否希望输入字段显示“123”(包括“.”)?还是仅仅是键入的数字?我下面的答案是只显示格式化值的解决方案,因此任何键入的“.”等都将被完全忽略。