Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - change input defaultValue by passing props

Consider this example:

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

I want to pass value into defaultValue as prop of dumb input component. However it never re-renders it.

like image 696
Kosmetika Avatar asked Jun 09 '15 09:06

Kosmetika


People also ask

How do I change the defaultValue in React?

To set a default value for an input element in React:Pass the default value as a parameter to the useState hook for controlled fields. Set the defaultValue prop on uncontrolled input fields.

How do you set a default value for an uncontrolled field?

In the React rendering lifecycle, the value attribute on form elements will override the value in the DOM. With an uncontrolled component, you often want React to specify the initial value, but leave subsequent updates uncontrolled. To handle this case, you can specify a defaultValue attribute instead of value .

How do you handle input change in React?

The standard way to handle form input value changes is to handle them with React. This is a technique called controlled components. We can create controlled components with input , textarea , and select elements. They maintain their own state, and updates are based on user input.


1 Answers

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.

like image 182
Sia Avatar answered Oct 19 '22 19:10

Sia