Bug: defaultValue property missing on select element ref

This issue has been tracked since 2022-09-18.

React version: 18.2.0

Steps To Reproduce

  1. Set a defaultValue on a <select /> element.
  2. After the element mounts, try to access that defaultValue through a ref of the element.

TypeScript is also missing the definition for defaultValue on HTMLSelectElement type

Link to code example: https://codesandbox.io/s/elated-orla-0p3dw7?file=/src/App.js

The current behavior

defaultValue always returns undefined

The expected behavior

defaultValueshould return the defined value

vkurchatkin wrote this answer on 2022-09-19

This does not have a lot to do with React.

HTMLInputElement has defaultValue property: https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement#properties

HTMLSelectElement does not: https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement#properties

antonio-costa wrote this answer on 2022-09-19

I understand that, but React prompts and console error if I use the "HTML-way" of using selected in <option />.

image

I believe this is was a decision to provide consistency across form elements (which I agree), but if the prop is not returned when I try to access it in a ref, then there's an inconsistency on this implementation, no?

How can I know what is the default value of a select element if React doesn't allow me use the selected prop but also doesn't provide the defaultValue property on the ref?

vkurchatkin wrote this answer on 2022-09-19

if the prop is not returned when I try to access it in a ref, then there's an inconsistency on this implementation, no?

React does indeed provide consistency, but only on the React side of things. It doesn't do anything to unify DOM APIs, because it is not it's job.

How can I know what is the default value of a select element if React doesn't allow me use the selected prop but also doesn't provide the defaultValue property on the ref?

You can definitely read selected when using ref:

useEffect(() => {
    console.log("select default value", selectRef.current.querySelector('option[selected]')?.value);
    console.log("input default value", inputRef.current.defaultValue);
  }, []);

But the most important question is: why do you even want to read defaultValue from DOM? You are the one who provides it, you already know it.

antonio-costa wrote this answer on 2022-09-19

I know I can read selected property, but React strongly advises against using it in the first place.

I'm trying to create a reusable hook for uncontrolled forms (similar to React Hook Form) and I'm comparing the current value with the default value in order to check whether an input has been changed.
This comparison can be done anywhere inside the form context, which may have several components nested and diverging trees.

My solution is to simply keep a reference to the fields registered in the form and access the DOM when I need information. That way I can freely change inputs without any unnecessary re-renders.

I can try to find a way around this, sure, but it just seems inconsistent that I'm advised against the selected property in favor of defaultValue property, but that one is not provided anywhere in the DOM just as selected property is.

vkurchatkin wrote this answer on 2022-09-19

I know I can read selected property, but React strongly advises against using it in the first place.

React advises you agains using selected as React prop, nothing more. It is unreasonable to expect it to actually add a nonexistent property to a DOM node. If you want to work with DOM directly it is up to you to handle differences like this

More Details About Repo
Owner Name facebook
Repo Name react
Full Name facebook/react
Language JavaScript
Created Date 2013-05-24
Updated Date 2022-10-03
Star Count 195549
Watcher Count 6650
Fork Count 40505
Issue Count 1119

YOU MAY BE INTERESTED

Issue Title Created Date Updated Date