Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remount ReactDOMInput when changing type #2242

Closed
wants to merge 1 commit into from
Closed

Remount ReactDOMInput when changing type #2242

wants to merge 1 commit into from

Conversation

syranide
Copy link
Contributor

IE8 throws if you change input type, It applies to all values of type (even unsupported ones).

React.renderComponent(<input type="radio" />, document.body);
React.renderComponent(<input type="checkbox" />, document.body);
[ERROR for attribute]  Could not get the type property. This command is not supported.
[ERROR for property]  "This command is not supported."

Additionally, all other versions of IE does not respect checked unless type="checkbox" or type="radio". So changing from type="textfield" to type="checkbox" while checked causes it to be unchecked. Which should be an issue for React, except that ReactDOMInput explicitly calls DOMPropertyOperations.setValueForProperty for every componentDidUpdate (source link). Why? Seems wasteful.

It seems to me that the correct solution (to all of this) is to consider a different type as a different component. type is a really weird HTML feature, which to me is akin to transforming span into div rather than remounting... which we don't.

cc @zpao @spicyj

(PS. PR just because, not saying we should take it as-is)

@zmsmith
Copy link

zmsmith commented Dec 2, 2014

I just ran into this bug working through an placeholder implementation for IE8. The workaround we came up with is to set a different key depending on the type of the input in order to signal to redraw the entire component when the type changes.

@sophiebits
Copy link
Collaborator

Accepted – @syranide feel free to merge after we branch for 0.13.

@syranide
Copy link
Contributor Author

@spicyj Hmm, I made getActualType return '' instead of 'text'. It works with 'text' currently in IE8 as it is mutated as a property. But #1510 will introduce removeAttribute for properties, so it would throw in IE8 when removing the property. Additionally, toggling between <input /> and <input type="text" /> seems incredibly rare and would also toggle the attribute in the DOM, while ultimately kind of irrelevant it seems preferable to treat type(null) !== type('text') for technical reasons and hopefully the user will be made aware of the unintentional toggling (hmm, perhaps a warning could make sense if really feel like it?).

Sounds good?

@sophiebits
Copy link
Collaborator

Yeah, okay.

@sophiebits
Copy link
Collaborator

This no longer works with the new implementation of ReactDOMInput. :\

@gaearon
Copy link
Collaborator

gaearon commented Mar 26, 2016

This no longer merges cleanly and has been stale for a few months so I am closing. Additionally, we no longer support IE8 officially in React 15, so bug fixes to it have a much lower priority now.

@gaearon gaearon closed this Mar 26, 2016
josephsavona added a commit that referenced this pull request May 15, 2024
Addresses T168684688 (#2242). MergeReactiveScopesThatInvalidateTogether does not 
merge scopes if their output is not guaranteed to change when their inputs do. 
So for example a case such as `{session_id: bar(props.bar)}` will not merge the 
scopes for `t0 = bar(props.bar)` and `t1 = {session_id: t0}`, because t0 isn't 
guaranteed to change when `props.bar` does, and we want to avoid recreating the 
t1 object unless it semantically changes. 

But there's a special case: if a scope has no dependencies, then we'll never 
execute it again anyway. So it doesn't matter what kind of value it produces and 
it's safe to merge with subsequent scopes: 

```javascript 

return {session_id: bar()} 

``` 

Without the reactive input, `bar()` will always return the same value since 
we'll only ever call it once anyway. So it's safe to then merge with the scope 
for the outer object literal.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants