George Mauer
George Mauer

Reputation: 122212

defaultValue change does not re-render input

I have no idea why this is not working

Demo

I have the following es6 code

const {createFactory, createClass, DOM: { label, input, button }} = React;

const tester = createFactory(createClass({
  render() {
      return label({}
               ,`Name: ${this.props.name}`
               ,input({defaultValue: this.props.name})
               ,button({onClick: this.changeName}, "Change")
             )
  },
  changeName() {
    this.setProps({name: "Wilma"})
  }
}) )

React.render(tester({name: "Fred"}), document.querySelector('body'))

Clicking the button clearly changes the props, but the old defaultValue is still in the input! So what gives? What am I doing wrong? is this a bug? Is there a workaround?

Upvotes: 18

Views: 13284

Answers (3)

Hari Om
Hari Om

Reputation: 31

If you want to change your defaultValue using State then please use key in your component. That's must be random generated.

Re-render DefaultValue when Value Changes in React

Like Below:

  const [keyData, setKeyData] = useState("Test");
<input 
  type="text" 
  defaultValue={keyData} 
  key={"OKAYG_" + (10000 + Math.random() * (1000000 - 10000))}
/>

Upvotes: 3

timbur
timbur

Reputation: 618

I found what seems to be a pretty good solution to this: Use the key prop to force rendering of an entirely new input.

In my particular case, I don't need the input to be controlled with its own onChange prop, as the form surrounding it ultimately controls the state within some store which populates the defaultValue. But the store's state might be asynchronously initialized/updated, and in which case the defaultValue should be updated. So here is a condensed version of my particular case:

import React, { PropTypes } from 'react';
import { Form } from 'provide-page';

const GatherContact = ({
  classes,
  onSubmit,
  movingContactName,
  movingContactEmail,
  movingContactPhone,
  userName,
  userEmail,
  userPhone
}) => (
  <Form onSubmit={onSubmit}>
    <div className={classes.GatherContact}>
      <h2 className={classes.GatherHeading}>
        How can we contact you?
      </h2>

      <input
        type="text"
        className={classes.GatherContactInput}
        placeholder="Name"
        name="movingContactName"
        key={`movingContactName:${movingContactName || userName}`}
        defaultValue={movingContactName || userName}
        required={true}
      />

      <input
        type="email"
        className={classes.GatherContactInput}
        placeholder="Email"
        name="movingContactEmail"
        key={`movingContactEmail:${movingContactEmail || userEmail}`}
        defaultValue={movingContactEmail || userEmail}
        required={true}
      />

      <input
        type="tel"
        className={classes.GatherContactInput}
        placeholder="Phone"
        name="movingContactPhone"
        key={`movingContactPhone:${movingContactPhone || userPhone}`}
        defaultValue={movingContactPhone || userPhone}
        required={true}
      />

      {userName
        ? undefined
        : (
          <input
            type="password"
            className={classes.GatherContactInput}
            placeholder="Password"
            name="userPassword"
            required={true}
            autoComplete="new-password"
          />
        )
      }
    </div>
  </Form>
);

GatherContact.propTypes = {
  classes: PropTypes.object.isRequired,
  onSubmit: PropTypes.func.isRequired,
  movingContactName: PropTypes.string.isRequired,
  movingContactEmail: PropTypes.string.isRequired,
  movingContactPhone: PropTypes.string.isRequired,
  userName: PropTypes.string.isRequired,
  userEmail: PropTypes.string.isRequired,
  userPhone: PropTypes.string.isRequired
};

export default GatherContact;

Upvotes: 41

Michael Parker
Michael Parker

Reputation: 12966

You only specify its default value, but don't tell it to change its value with a change to props.

,input({value: this.props.name})

Will change the value when this.props.name changes.

http://output.jsbin.com/melitecimo

Upvotes: 8

Related Questions