React - 通过传递props更改输入默认值

IT技术 javascript forms reactjs default-value
2021-04-14 23:35:58

考虑这个例子:

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

我想将值defaultValue作为哑输入组件的props传递但是它永远不会重新渲染它。

6个回答

正如前面提到的答案,defaultValue仅在表单的初始加载时设置。在那之后,它不会“自然”更新,因为目的只是设置初始默认值。

如果您需要将 a 传递key给包装器组件(例如在您的FieldApp组件上),您可以解决此问题,但在更实际的情况下,它可能是一个form组件。一个好的key是传递给表单的资源的唯一值 - 例如存储在数据库中的 id。

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

<div key={this.props.value}>
    <input type="text" defaultValue={this.props.value || ''} />
</div>

在更复杂的表单案例中,例如,如果您的 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
}

当使用不受控制的表单输入时,我们通常在提交之后才关心这些值,所以这就是为什么只在您真正想要更新 defaultValues 时才强制重新渲染更为理想(提交之后,而不是每次更改时)个人输入)。

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

这应该是最好的答案
2021-05-23 23:35:58
使用值作为键只是一种黑客行为,它会根据值的变化多次挂载元素。尽管它可以解决您的问题,但它并不是更新输入值的最佳方法。实际上它不会更新值而是创建一个新值(在极端情况下会导致内存泄漏)。最好使用受控输入字段而不是此解决方案。
2021-05-27 23:35:58
你是一个救生员 <3
2021-06-09 23:35:58
你拯救了我的一天!
2021-06-10 23:35:58
这应该是最好的答案
2021-06-16 23:35:58

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

我相当肯定这与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>
          );
      }
  });

这是一个显示更改的plunker

这是解决不受控制的输入的最干净的方法吗?此外,我onChange在您的示例中没有看到任何功能。
2021-05-22 23:35:58
太好了,值设置和onKeyUp/onKeyPress等其他键有一个bug,所以如果你需要,在某些情况下,ex的onKeyUp事件,你应该在同一个函数上设置onChange,否则不会更新value属性.
2021-06-16 23:35:58
@JohnnyQ 不受控制的组件不需要onChange. 通常,该值是使用ref.
2021-06-17 23:35:58

您可以有条件地进行输入,然后每次要强制更新时,defaultValue您只需要卸载输入,然后立即再次渲染它。

问题在这里:

onClick={this.changeTo.bind(null, 'Whyyyy?')}

我很好奇你为什么绑定到 null。

您想绑定到“this”,以便 changeTo 将在 THIS 对象中设置状态。

试试这个

<button onClick={this.changeTo.bind(this, 'Whyyyy?')}>Change to "Whyyyy?"</button>
<button onClick={this.changeTo.bind(this, void 0)}>Change to undefined</button>

在 Javascript 中,当一个函数被调用时,它在它被调用的范围内被调用,而不是在它被写入的地方(我知道,这似乎违反直觉)。为了确保在你编写它的上下文中调用它,你需要'.bind(this)'。

要了解有关绑定和函数范围的更多信息,有很多在线教程(有些比其他教程要好得多)-您可能会喜欢这个:http : //ryanmorr.com/understanding-scope-and-context-in-javascript/

如果您使用的是 firefox 或 chrome,我还建议您使用 React Dev 工具,这样您就可以看到 state.message 没有改变:https ://facebook.github.io/react/blog/2015/09 /02/new-react-developer-tools.html