-
Notifications
You must be signed in to change notification settings - Fork 46.7k
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
Clear button on iOS date input does not return correct event value #8938
Comments
Purely speculative, but I wonder if Happy to triage this, @aweary. |
Updating to use |
@nhunzaker feel free to look into this 👍 I did some very shallow/quick debugging and from what I can tell iOS Safari is not updating the DOM element's It would be worth seeing if we could reproduce this behavior without React. |
Without React: |
@jquense no need to dig too deep into this, but the changes to |
☝️ Sorry, bit of user error... Going to keep digging. |
Hitting Clear will indeed revert to the class DateInput extends React.Component {
componentDidUpdate(prevProps) {
if (prevProps.value !== this.props.value) {
this.refs.input.defaultValue = "";
}
}
render() {
return <input ref="input" type="date" value={this.props.value} />;
}
} |
Tried the solution by @mdoelker but unfortunately didn't have any luck. The clear button still doesn't work but the defaultValue of the input element on the page is "". |
@mdoelker's solution worked for me as long as I removed the check comparing prevProps.value to props.value (that is, on every componentDidUpdate, I manually set the input's default value to ""). |
I'm still encountering this. Tapping on |
The workarounds listed so far didn't work for me. The following worked perfectly though on onInput(e) {
const target = e.nativeEvent.target;
function iosClearDefault() { target.defaultValue = ''; }
window.setTimeout(iosClearDefault, 0);
} |
We received a new issue for this (#12313) with some additional test cases. I've migrated over the issuer's findings to this issue: Reproduced on iPhone 6 iOS 11.2.2 Safari.
Demo React 16.2: jsfiddle Thanks @smollweide for your time preparing these! |
I was able to fix it with: const getRef = (ref) => { if (ref) ref.defaultValue = "" };
//...
<input type="date"
onChange={(event) => {
log('change controlled, value: ' + event.target.value);
this.setState({ value: event.target.value });
}}
value={this.state.value}
ref={getRef} /> Demo React 16.2 jsfiddle |
That's very interesting. Both cases mentioned get me curious about this part:
Is it possible that synchronizing the value attribute is messing up the value property reported by Safari when clearing the value? I wonder if removing attribute syncing in a local build would alleviate the problem. My guess is that there is a race between the browser and React, but I can't really reason about what that looks like. I'll dig into this a bit more. |
@nhunzaker When you click clear in Chrome it will reset value to empty string but Safari will reset value to |
Here is another solution to this issue in case someone needs it. https://codepen.io/joseplatas/pen/yWQYeq class App extends React.Component{
state = {
value: "2011-11-11"
}
inputRef = React.createRef();
componentDidMount(){
/*
necessary if value is being set in mount,
otherwise the clear won't work on the first click
*/
this.inputRef.current.defaultValue = "";
}
handleOnChange = (event)=>{
this.setState({
value: event.target.value
});
/*
defaultValue seems to reset every time on the handleChange call,
we need to set defaultValue again as it is change.
setTimeout is required for this to work, it needs a small delay
otherwise defaultValue gets unset
*/
const target = event.target;
setTimeout(()=>{
target.defaultValue = "";
}, 100);
}
render(){
return(
<div>
<input
ref={this.inputRef}
type="date"
value={this.state.value}
onChange={this.handleOnChange}
/*
NOTE: don't set defaultValue here because it will create a warning
React will warn you that:
Input elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both).
*/
//defaultValue=""
/>
</div>
)
}
} |
I was experimenting with the solution of @joseplatas above for a while, but couldn't get the refs part working. Then I figured that making Clear work on first click can be done if I can clear defaultValue at the time of focusing the input, so attaching a callback to return (
<input
type="date"
value={this.state.value}
onChange={this.handleOnChange}
onFocus={(event) => event.nativeEvent.target.defaultValue = ""}
/>
); |
Interesting. This looks like yet another side effect of assigning the value attribute dynamically, synchronizing it with value. @philipp-spiess or @gaearon do you know of a place where we're tracking these issues? This issue might go away if we turn on the react/packages/shared/ReactFeatureFlags.js Lines 48 to 50 in 34aaec6
(EDIT: reading the comments, it looks like I'm re-remembering this for the second or third time 😭) |
Didn't work due to iOS bug. For more information: facebook/react#8938
Is this issue still open? I'm interested in working on it and would love to contribute. |
Bug
For iOS only.
When pressing
clear
on a date input, theonChange
event is fired butevent.target.value
is showing the original value rather than an empty string.What is the current behavior?
On Chrome and Android, when the clear button is pressed the onChange event has a value of
''
.On iOS when the clear button is pressed the onChange event has a value of
previousValue
.Demo
https://output.jsbin.com/zojuteloto/5/
Try on Chrome/Android. Then on iOS.
What is the expected behavior?
Value should be returned an an empty string.
Versions
Affects React 15+ & iOS 10. Unsure of previous versions.
The text was updated successfully, but these errors were encountered: