React - change input defaultValue by passing props React - change input defaultValue by passing props reactjs reactjs

React - change input defaultValue by passing props


As a previous answer mentioned, defaultValue only gets set on initial load for a form. After that, it won't get "naturally" updated because the intent was only to set an initial default value.

You can get around this if you need to by passing a key to the wrapper component, like on your Field or App component, though in more practical circumstances, it would probably be a form component. A good key would be a unique value for the resource being passed to the form - like the id stored in the database, for example.

In your simplified case, you could do this in your Field render:

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

In a more complex form case, something like this might get what you want if for example, your onSubmit action submitted to an API but stayed on the same page:

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}

When using uncontrolled form inputs, we generally don't care about the values until after they are submitted, so that's why it's more ideal to only force a re-render when you really want to update the defaultValues (after submit, not on every change of the individual input).

If you're also editing the same form and fear the API response could come back with different values, you could provide a combined key of something like id plus timestamp.


defaultValue only works for the initial load. After that, it won't get updated. You need to maintain the state for you Field component:

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


I'm fairly certain this has to do with Controlled vs. Uncontrolled inputs.

If I understand correctly, since your <input> is Uncontrolled (doesn't define a value attribute), then the value will always resolve to the value that it is initialized with. In this case Hello!.

In order to overcome this issue, you can add a value attribute and set it during the 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>          );      }  });

Here is a plunker showing the change.