为什么我的输入值没有使用React更新?

时间:2016-04-18 00:29:19

标签: javascript reactjs

我的组件中有以下代码。当我更新某些东西时它会被调用,从而取代UI中的一堆东西。一切都在更新,除了用户看到的输入值。

let input = {
  id: 'discount-' + geo + '-' + segment,
  value: percentage,
  disabled: applyToAll,
  placeholder: '0.00'
};

cells.push(
  <td key={'cell-' + geo + '-' + segment} className="discount-segment cfix">
    <Text {...input} />
  </td>
);

这是<Text>返回的内容,为清晰起见删除了一些内容

return (
  <div className={containerClasses.join(' ')} id={'field-container-' + id}>
    {label}
    <input
      autoComplete="off"
      type="text"
      id={id}
      ref="input"
      {...extraProps}
      name={id}
      className={classes.join(' ')}
      defaultValue={this.props.value}
      onChange={this.props.onChange}
      />
  </div>
);

一切都很好。我们假设percentage值在开始时为5,它会在字段中显示5。然后我做了一些将percentage更新为50的内容。(控制台日志将在重新渲染时显示正确的数字)。但是,该值仅在UI中显示5。我在输入字段上使用defaultValue,但我认为应该改变,因为整个事物从父级重新渲染。

修改 更新了<Text>以设置value而不是defaultValue。但是,我需要使用state在用户输入时更新值。然后,当我重新渲染时,我发送了具有适当价值的新道具,但当然道具并未更新。 Catch-22对我来说。

3 个答案:

答案 0 :(得分:11)

您需要执行以下几个步骤:

  1. 您的输入需要使用valueonChange道具,不要使用defaultValue
  2. 使用道具初始化您的状态以设置默认值
  3. 在道具更改时更新您的状态
  4. 所以,例如:

    const MyComponent = React.createClass({
    
      propTypes: {
        defaultInputValue: React.PropTypes.string
      },
    
      getInitialState() {
        return {
          inputValue: this.props.defaultInputValue
        };
      },
    
      componentWillReceiveProps(nextProps) {
        if (nextProps.defaultInputValue !== this.props.inputValue) {
          //Forcibly overwrite input value to new default if the default ever changes
          this.setState({inputValue: nextProps.defaultInputValue});
        }
      },
    
      render() {
        return <input type="text"
                      value={this.state.inputValue}
                      onChange={e => this.setState({inputValue: e.target.value})} />;
      }
    });
    

    一般来说,道具的初始化状态是禁忌。如果我在代码审查中看到这种情况,我可能会有点畏缩,因为可能有一些行为可以简化。

    你也可以这样做:

    <input value={this.state.inputValue || this.props.defaultInputValue} />
    

    如果您清除了输入,输入的值将恢复为prop值。在这种情况下,你不必用新道具强行覆盖状态。

答案 1 :(得分:0)

AoA
我们可以这样做。我们必须使用onChnage()事件。

<Input placeholder="as_you_want"
       value={this.state.as_your_state}
       onChange={e => {
           this.setState({ as_your_state: e.target.value });
           this.value = this.state.as_your_state;
       }}
/>

希望这行得通。

答案 2 :(得分:0)

componentWillReceivePropsdeprecated now,甚至它的后继 getDerivedStateFromProps 也是 recommended against。为了圆圆“我需要管理一个文本输入的状态(state),但我也需要它在我重新渲染时更新它的初始值(props)”,React博客推荐了using a key道具。当 key 发生变化时,组件重新挂载,props 可以重新初始化 state。

为了在输入发生任何变化时主动强制组件刷新,我会使用

    <Text {...input} key={JSON.stringify(input)}/>

然后你可以像普通的受控表单一样使用value={this.state.value},但是你可以设置this.state.value = props.value,它每次都会改变。