React - 通过传递props更改输入defaultValue

Kos*_*ika 21 javascript forms default-value reactjs

考虑这个例子:

var Field = React.createClass({
    render: function () {
        // never renders new value...
        return (
            <div>
                <input type="text" defaultValue={this.props.value || ''} />
            </div>
        );
    }
});

var App = React.createClass({
    getInitialState: function () {
        return {value: 'Hello!'};
    },

    changeTo: function (str) {
        this.setState({value: str});
    },

    render: function () {
        return (
            <div>
                <Field value={this.state.value} />
                <button onClick={this.changeTo.bind(null, 'Whyyyy?')}>Change to "Whyyyy?"</button>
                <button onClick={this.changeTo.bind(null, void 0)}>Change to undefined</button>
            </div>
        );
    }
});

React.render(
    <App />,
    document.getElementById('app')
);
Run Code Online (Sandbox Code Playgroud)

我想将值传递给defaultValue哑输入组件的支柱.然而,它永远不会重新呈现它.

Sia*_*Sia 54

如前所述,defaultValue只有在表单的初始加载时才会设置.之后,它不会"自然"更新,因为意图只是设置初始默认值.

如果需要,可以通过传递key给包装器组件来解决这个问题,就像你FieldApp组件一样,尽管在更实际的情况下,它可能是一个form组件.key对于传递给表单的资源,一个商品就是一个唯一的值 - 比如存储在数据库中的id.

在简化的情况下,您可以在Field渲染中执行此操作:

<div key={this.props.value}>
    <input type="text" defaultValue={this.props.value || ''} />
</div>
Run Code Online (Sandbox Code Playgroud)

在一个更复杂的形式的情况下,像这样的东西可能会得到你想要的,例如,你的onSubmit动作提交给API但保持在同一页面上:

const Form = ({item, onSubmit}) => {
  return (
    <form onSubmit={onSubmit} key={item.id}>
      <label>
        First Name
        <input type="text" name="firstName" defaultValue={item.firstName} />
      </label>
      <label>
        Last Name
        <input type="text" name="lastName" defaultValue={item.lastName} />
      </label>
      <button>Submit!</button>
    </form>
  )
}

Form.defaultProps = {
  item: {}
}

Form.propTypes = {
  item: PropTypes.object,
  onSubmit: PropTypes.func.isRequired
}
Run Code Online (Sandbox Code Playgroud)

当使用不受控制的表单输入时,我们通常不会关心这些值,直到它们被提交之后,这就是为什么当你真的想要更新defaultValues时(仅在提交之后,而不是在每次更改时)强制重新渲染更为理想个人意见).

如果您还在编辑相同的表单并担心API响应可能会返回不同的值,则可以提供id加时间戳等组合键.

  • 你是一个救生员 &lt;3 (5认同)
  • 你拯救了我的日子! (3认同)
  • 这应该是最好的答案 (3认同)
  • 这应该是最好的答案 (2认同)
  • 使用值作为键只是一个hack,它会随着值的更改将元素安装多次。尽管它可以解决您的问题,但这并不是更新输入值的最佳方法。实际上,它不会更新值,而是创建一个新值(在极端情况下,它可能导致内存泄漏)。最好使用受控输入字段代替此解决方案。 (2认同)

dro*_*gon 12

defaultValue仅适用于初始加载.之后,它将不会更新.你需要为你保持状态Field组件:

var Field = React.createClass({
    //transfer props to state on load
    getInitialState: function () {
        return {value: this.props.value};
    },
    //if the parent component updates the prop, force re-render
    componentWillReceiveProps: function(nextProps) {
         this.setState({value: nextProps.value});
    },
    //re-render when input changes
    _handleChange: function (e){
        this.setState({value: e.target.value});
    },
    render: function () {
        // render based on state
        return (
            <div>
                <input type="text" onChange={this._handleChange} 
                                   value={this.state.value || ''} />
            </div>
        );
    }
});
Run Code Online (Sandbox Code Playgroud)


Dav*_*yon 6

我相当肯定这与Controlled vs. Uncontrolled 输入有关

如果我理解正确,因为您<input>是不受控制的(未定义value属性),那么该值将始终解析为初始化时使用的值。在这种情况下Hello!

为了克服这个问题,您可以添加一个value属性并在以下过程中设置它onChange

var Field = React.createClass({
      render: function () {
          // never renders new value...
          return (
              <div>
                  <input type="text" defaultValue={this.props.default || ''} value={this.props.value} />
              </div>
          );
      }
  });
Run Code Online (Sandbox Code Playgroud)

这是一个显示更改的plunker