1

So I noticed a very odd behaviour when it comes to defaultValue. When you re-render using defaultValue parts of it may not register the re-render and maintains the initial rendering of the state.

See pic: enter image description here

However switching from defaultValue to value fixes this issue.

This is both a heads up to other people who may be experiencing this issue and a question as to why this occurs.

The line of code that generates this:

      inner_array.push(
        <div key={j}>
          <input defaultValue={final_line} style={{ width: "100%" }} onClick={this.highlight} ></input>
        </div>)

This eventually gets map'd like this:

{Object.keys(data).map( (item, index) => (!item.match(/default/i)) ? <li key={index}>{item}</li> : "")}

Extra information

So the thing that causes the re-render is setState. I'm overriding a previous object with another object.

Example

defaultValue and value in action: Fiddle: https://jsfiddle.net/69z2wepo/74509/

5
  • My guess is that it may be related to your key prop being collided when you change the list of items. It's not recommended to use an array index as a key. Try to replace it to anything that is unique. Commented Mar 24, 2017 at 3:30
  • @AlexM Hmm, doesn't seem to be the case. What are the actual purpose of the keys anyway? They seem to function alright without them, I just add them in because the console throws a bit of a hissy fit if I don't Commented Mar 24, 2017 at 3:36
  • 1
    I checked your example. Actually, that was the case. I'll give you an explanation in a few minutes. Commented Mar 24, 2017 at 3:44
  • 1
    Here's an example with unique key prop: jsfiddle.net/b9qy7o3x Notice that the key now consists not only of index but also of object ID, which makes it unique. I'll post more detailed answer soon Commented Mar 24, 2017 at 4:00
  • @AlexM that's interesting. Why doesn't something as simple as "something"+index work? I've updated the fiddle to show both defaultValue and normal value Commented Mar 24, 2017 at 4:04

1 Answer 1

1

The important thing about defaultValue property is that it only set to an input element when it's mounted.

In your example, you have two lists of elements, and you use an array index as a key. When you switch the source list (array or object, doesn't really matter becase you'll eventually map it to an array of elements), some of your keys stay the same (index 0 and 1), so React just updates those elements instead of unmounting them and mounting the new ones. And, as you know, defaultValue is only set once, when the element is being mounted. So changes to defaultValue do not take effect when the component updates.

To fix this issue, you need to force React to re-mount <input> instead of updating them. It can be done by making sure that the key props change when you switch the list. I updated your example ( https://jsfiddle.net/b9qy7o3x/ ) so that it adds an ID of the list to the key prop, making it always unique.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.