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

时间:2015-10-27 19:41:03

标签: reactjs

我想允许用户在输入字段中输入更改而不将其传播到父级。每当我不想传播时,我都会通过返回onChange函数来完成此操作。然而,这似乎取消了我输入的字符。

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

export default class NumberField extends React.Component {
  render () {
    var props = this.props;

    var format = props.formatter || formatters.number;
    return (
      <div>
        <label>{props.inputLabel}</label>
        <input
          type="text"
          name={props.name}
          onChange={this.onChange.bind(this)}
          value={!_.isUndefined(props.value) ? format(props.value) : null}
        />
      </div>
    );
  }

  onChange (e) {
    var numValue = formatters.stringToFloat(e.target.value);
    //they added a . or , we don't propagate change
    if (this.props.value === numValue) {
      return;
    }

    if (this.props.onChange) {
      this.props.onChange({
        value: numValue,
        valid: validation.isValid(numValue, this.props.validation)
      });
    }
  }
};

2 个答案:

答案 0 :(得分:0)

到目前为止,我提出的最佳方法是维护一个单独的formattedValue状态,只有当我想覆盖默认格式时才会设置该状态。它有效,但似乎是一个非常肮脏的解决方案。

&#13;
&#13;
export default class NumberField extends React.Component {
  constructor () {
    super();
    this.state = {
      formattedValue: null
    };
  }

  render () {
    var props = this.props;
    var state = this.state;
    var format = props.formatter || formatters.number;
    var inputValue = state.formattedValue || (
      !_.isUndefined(props.value) ?
        format(props.value) :
        null
      );
    return (
      <div>
        <label>{props.inputLabel}</label>
        <input
          type="text"
          name={props.name}
          onChange={this.onChange.bind(this)}
          value={inputValue}
        />
      </div>
    );
  }

  onChange (e) {
    var numValue = formatters.stringToFloat(e.target.value);
    //they added a . or , we don't propagate change
    if (this.props.value === numValue) {
      this.setState({
        formattedValue: e.target.value
      });
    } else {
      this.setState({
        formattedValue: null
      });
    }

    if (this.props.onChange) {
      this.props.onChange({
        value: numValue,
        valid: validation.isValid(numValue, this.props.validation)
      });
    }
  }
};
&#13;
&#13;
&#13;

答案 1 :(得分:0)

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

  • 所有用户输入(包括。和)都处于状态并在输入字段中呈现给用户。
  • 仅当格式正确时,才会调用父onChange()

父级实际上可能会执行onChange()调用触发的重新渲染。因此,我们需要确保最后输入的字符在状态中更新,然后才会调用父{〗{}

您的组件如下所示:

onChange()

这可能有点过分:你保持一个你也与父母沟通的状态(格式化值)。如果您的父级总是传递新转发的输入,那么您可以使您的组件更简单: 没有状态,只是根据道具重新渲染。

如果在输入字段中向用户显示的值可能与您与父母的通信不同,则您只需要状态。