facebook / react

The library for web and native user interfaces.
https://react.dev
MIT License
227.6k stars 46.43k forks source link

Bug: can not pass some special custom attribute such as `size` #20159

Open mh-alahdadian opened 3 years ago

mh-alahdadian commented 3 years ago

As we know after react 16 we can use any custom attributes in dom elements but there is a bug which some special attributes (such as size) are not forwarding to dom element

screenshot

React version: 16.13 & 17.0

Steps To Reproduce

  1. render a dom element with some custom attributes including size
  2. inspect output and you will see your custom attributes but size

Link to code example: https://codesandbox.io/s/setting-size-as-custom-attr-hdom2?file=/src/App.js

The current behavior

size attribute will not show in output

The expected behavior

size should be in output

ssslambda commented 3 years ago

+1 (React 17.0.1), size is passed to DOM, not component props

eps1lon commented 3 years ago

Thanks for the report.

React 16.13.1 has the same behavior though. It needs to be a number in <select /> and <input /> and therefore React expects this type for every DOM component

  1. <h1 size="1" /> is working
  2. <select size="1" /> is working
  3. <select size="size" /> is not working and issues no warning

I can see two issues here:

  1. React silences errors when setting size It might be useful to add a dev warning if the size attribute has an invalid value where the DOM component implements it. For example, setting someInputElement.size = "size" throws a DOMException. React might be able to leverage that.
  2. React does not treat size as an attribute on elements other than <input /> and <select />

Looks like https://github.com/facebook/react/issues/12694 discussed this regarding custom components.

I could make some implementation arguments about why <h1 size="size" /> should be allowed:

  1. h1.setAttribute('size', 'size') works
  2. h1.size = 'size' works

Though at a higher level it might be confusing if you overload the size attribute by meaning different things depending on the DOM component. Note that React always treats specified HTML attributes the same on every element. <h1 open="whatever" /> ignores "whatever", <h1 span="span" /> and <h1 size="size" /> all do not work because these attributes would have the incorrect type on the elements where they make sense.

Maybe a warning like

The size attribute value of "size" has the wrong type. The size attribute is a well-known HTML attribute. You should be using data-size="size" instead.

ghost commented 3 years ago

I can work on adding some warning here!

mh-alahdadian commented 3 years ago

I could make some implementation arguments about why <h1 size="size" /> should be allowed:

  1. h1.setAttribute('size', 'size') works
  2. h1.size = 'size' works

Though at a higher level it might be confusing if you overload the size attribute by meaning different things depending on the DOM component. Note that React always treats specified HTML attributes the same on every element. <h1 open="whatever" /> ignores "whatever", <h1 span="span" /> and <h1 size="size" /> all do not work because these attributes would have the incorrect type on the elements where they make sense.

Maybe a warning like

The size attribute value of "size" has the wrong type. The size attribute is a well-known HTML attribute. You should be using data-size="size" instead.

I think that react should ignore props doesn't know about them we could use size="size" out of input and select component because they have no meaning in html and react should not prevent using them

and also maybe there was a size attribute with string value in custom html elements and 3rd-party libraries using Web Components which must be worked without problem as mentioned in docs