Set the correct initial value on input range (#12939)

* Set the correct initial value on input range

* Add description and update value diff check for input range

* add isHydrating argument and tests

* update node value according to isHydrating
This commit is contained in:
Maxime Nory
2018-05-31 17:23:26 -04:00
committed by Nathan Hunzaker
parent 65ab53694f
commit 36546b5137
3 changed files with 36 additions and 6 deletions
@@ -348,9 +348,13 @@ describe('ReactDOMServerIntegration', () => {
ControlledSelect;
beforeEach(() => {
ControlledInput = class extends React.Component {
static defaultProps = {
type: 'text',
initialValue: 'Hello',
};
constructor() {
super();
this.state = {value: 'Hello'};
super(...arguments);
this.state = {value: this.props.initialValue};
}
handleChange(event) {
if (this.props.onChange) {
@@ -361,6 +365,7 @@ describe('ReactDOMServerIntegration', () => {
render() {
return (
<input
type={this.props.type}
value={this.state.value}
onChange={this.handleChange.bind(this)}
/>
@@ -551,6 +556,27 @@ describe('ReactDOMServerIntegration', () => {
expect(changeCount).toBe(0);
});
it('should not blow away user-interaction on successful reconnect to an uncontrolled range input', () =>
testUserInteractionBeforeClientRender(
<input type="text" defaultValue="0.5" />,
'0.5',
'1',
));
it('should not blow away user-interaction on successful reconnect to a controlled range input', async () => {
let changeCount = 0;
await testUserInteractionBeforeClientRender(
<ControlledInput
type="range"
initialValue="0.25"
onChange={() => changeCount++}
/>,
'0.25',
'1',
);
expect(changeCount).toBe(0);
});
it('should not blow away user-entered text on successful reconnect to an uncontrolled checkbox', () =>
testUserInteractionBeforeClientRender(
<input type="checkbox" defaultChecked={true} />,
+2 -2
View File
@@ -530,7 +530,7 @@ export function setInitialProperties(
// TODO: Make sure we check if this is still unmounted or do any clean
// up necessary since we never stop tracking anymore.
inputValueTracking.track((domElement: any));
ReactDOMFiberInput.postMountWrapper(domElement, rawProps);
ReactDOMFiberInput.postMountWrapper(domElement, rawProps, false);
break;
case 'textarea':
// TODO: Make sure we check if this is still unmounted or do any clean
@@ -1077,7 +1077,7 @@ export function diffHydratedProperties(
// TODO: Make sure we check if this is still unmounted or do any clean
// up necessary since we never stop tracking anymore.
inputValueTracking.track((domElement: any));
ReactDOMFiberInput.postMountWrapper(domElement, rawProps);
ReactDOMFiberInput.postMountWrapper(domElement, rawProps, true);
break;
case 'textarea':
// TODO: Make sure we check if this is still unmounted or do any clean
+6 -2
View File
@@ -205,7 +205,11 @@ export function updateWrapper(element: Element, props: Object) {
}
}
export function postMountWrapper(element: Element, props: Object) {
export function postMountWrapper(
element: Element,
props: Object,
isHydrating: boolean,
) {
const node = ((element: any): InputWithWrapperState);
if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
@@ -214,7 +218,7 @@ export function postMountWrapper(element: Element, props: Object) {
// Do not assign value if it is already set. This prevents user text input
// from being lost during SSR hydration.
if (currentValue === '') {
if (!isHydrating) {
// Do not re-assign the value property if there is no change. This
// potentially avoids a DOM write and prevents Firefox (~60.0.1) from
// prematurely marking required inputs as invalid