简体   繁体   English

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

[英]Why isn't my input value updating with React?

I have the following code in my component.我的组件中有以下代码。 It will get called when I update certain things, thereby replacing a bunch of things in the UI.当我更新某些东西时它会被调用,从而替换 UI 中的一堆东西。 Everything is updating EXCEPT the value of the input as seen by the user.一切都在更新,除了用户看到的输入值。

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>
);

This is what <Text> returns, with things removed for clarity这是<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>
);

Everything renders fine.一切都很好。 Let's say the percentage value is 5 on start, it will show 5 in the field.假设开始时percentage值为5 ,它将在字段中显示5 I then do something else that updates percentage to 50. (A console log will show the right number on re-render).然后我做一些其他事情,将percentage更新为 50。(控制台日志将在重新渲染时显示正确的数字)。 However the value is only showing 5 in the UI still.然而,该值仍然只在 UI 中显示5 I am using defaultValue on the input field, but I figure that should be changing as the whole thing re-renders from parent.我在输入字段上使用defaultValue ,但我认为随着整个事物从父级重新呈现,这应该会发生变化。

Edit Updated <Text> to set value instead of defaultValue .编辑更新<Text>以设置value而不是defaultValue However then I need to use state to update the value when user types.但是,当用户键入时,我需要使用state来更新值。 Then when I re-render, I'm sending in new props with proper value, but of course props isn't updated.然后当我重新渲染时,我发送了具有适当价值的新道具,但道具当然没有更新。 Catch-22 for me. Catch-22 对我来说。

You need to perform a couple of steps:您需要执行几个步骤:

  1. Your input needs to only use the value and onChange props, do not use defaultValue您的输入需要使用valueonChange道具,不要使用defaultValue
  2. Initialize your state using your props to set your default value使用您的道具初始化您的状态以设置您的默认值
  3. Update your state when your props change当你的道具改变时更新你的状态

So, for example:因此,例如:

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})} />;
  }
});

In general initializing state off of props is a no-no.一般来说,从 props 初始化状态是一个禁忌。 I would probably cringe a little bit if I saw this come across in a code review as there is probably some behavior that can be simplified.如果我在代码审查中看到这种情况,我可能会有点畏缩,因为可能有一些可以简化的行为。

You can also do:你也可以这样做:

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

Such that the value of the input reverts to the prop value if you ever clear out the input.这样,如果您清除输入,输入的值将恢复为 prop 值。 In this case you wouldn't have to forcibly overwrite the state with the new props.在这种情况下,您不必用新道具强行覆盖状态。

We can do it as this.We Must have to use onChnage() Event.我们可以这样做。我们必须使用 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;
       }}
/>

Hope This Works.希望这有效。

componentWillReceiveProps is deprecated now , and even its successor getDerivedStateFromProps is recommended against . componentWillReceiveProps现在已经过时,甚至它的后继getDerivedStateFromProps建议反对 To square the circle of "I need to manage the state of a text input (state), but I also need it to update its initial value when I re-render (props)", the React blog recommended using a key in the props.为了圆“我需要管理一个文本输入的状态(state),但我也需要它在我重新渲染时更新它的初始值(props)”,React博客推荐在props中使用一个key . When the key changes, the component remounts and props can initialize state anew.当 key 发生变化时,组件会重新挂载,props 可以重新初始化 state。

To aggressively force the component to refresh whenever anything about the input changes, I would use为了在输入发生任何变化时积极强制组件刷新,我会使用

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

Then you can use value={this.state.value} like a normal controlled form, but you can set this.state.value = props.value and it will change every time.然后你可以像正常的受控形式一样使用value={this.state.value} ,但是你可以设置this.state.value = props.value并且它每次都会改变。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM