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

Make uncontrolled -> controlled warning clearer #17070

Merged
merged 7 commits into from Apr 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -184,7 +184,7 @@ describe('DOMPropertyOperations', () => {
container,
),
).toErrorDev(
'A component is changing a controlled input of type text to be uncontrolled',
'A component is changing a controlled input to be uncontrolled',
);
if (disableInputAttributeSyncing) {
expect(container.firstChild.hasAttribute('value')).toBe(false);
Expand Down
Expand Up @@ -178,9 +178,9 @@ describe('ReactDOMComponentTree', () => {
const component = <Controlled />;
const instance = ReactDOM.render(component, container);
expect(() => simulateInput(instance.a, finishValue)).toErrorDev(
'Warning: A component is changing an uncontrolled input of ' +
'type text to be controlled. Input elements should not ' +
'switch from uncontrolled to controlled (or vice versa). ' +
'Warning: A component is changing an uncontrolled input to be controlled. ' +
'This is likely caused by the value changing from undefined to ' +
'a defined value, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: ' +
'https://fb.me/react-controlled-components',
Expand Down
101 changes: 55 additions & 46 deletions packages/react-dom/src/__tests__/ReactDOMInput-test.js
Expand Up @@ -475,8 +475,7 @@ describe('ReactDOMInput', () => {
expect(() =>
ReactDOM.render(<input type="text" defaultValue="1" />, container),
).toErrorDev(
'A component is changing a controlled input of type ' +
'text to be uncontrolled.',
'A component is changing a controlled input to be uncontrolled.',
);
expect(node.value).toBe('0');
});
Expand Down Expand Up @@ -854,8 +853,7 @@ describe('ReactDOMInput', () => {
container,
),
).toErrorDev(
'A component is changing a controlled input of type ' +
'submit to be uncontrolled.',
'A component is changing a controlled input to be uncontrolled.',
);

const node = container.firstChild;
Expand All @@ -874,8 +872,7 @@ describe('ReactDOMInput', () => {
container,
),
).toErrorDev(
'A component is changing a controlled input of type ' +
'reset to be uncontrolled.',
'A component is changing a controlled input to be uncontrolled.',
);

const node = container.firstChild;
Expand Down Expand Up @@ -1268,8 +1265,9 @@ describe('ReactDOMInput', () => {
);
ReactDOM.render(stub, container);
expect(() => ReactDOM.render(<input type="text" />, container)).toErrorDev(
'Warning: A component is changing a controlled input of type text to be uncontrolled. ' +
'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
'Warning: A component is changing a controlled input to be uncontrolled. ' +
'This is likely caused by the value changing from a defined to ' +
'undefined, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components\n' +
' in input (at **)',
Expand All @@ -1286,8 +1284,9 @@ describe('ReactDOMInput', () => {
).toErrorDev([
'`value` prop on `input` should not be null. ' +
'Consider using an empty string to clear the component or `undefined` for uncontrolled components',
'Warning: A component is changing a controlled input of type text to be uncontrolled. ' +
'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
'Warning: A component is changing a controlled input to be uncontrolled. ' +
'This is likely caused by the value changing from a defined to ' +
'undefined, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components\n' +
' in input (at **)',
Expand All @@ -1305,8 +1304,9 @@ describe('ReactDOMInput', () => {
container,
),
).toErrorDev(
'Warning: A component is changing a controlled input of type text to be uncontrolled. ' +
'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
'Warning: A component is changing a controlled input to be uncontrolled. ' +
'This is likely caused by the value changing from a defined to ' +
'undefined, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components\n' +
' in input (at **)',
Expand All @@ -1319,8 +1319,9 @@ describe('ReactDOMInput', () => {
expect(() =>
ReactDOM.render(<input type="text" value="controlled" />, container),
).toErrorDev(
'Warning: A component is changing an uncontrolled input of type text to be controlled. ' +
'Input elements should not switch from uncontrolled to controlled (or vice versa). ' +
'Warning: A component is changing an uncontrolled input to be controlled. ' +
'This is likely caused by the value changing from undefined to ' +
'a defined value, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components\n' +
' in input (at **)',
Expand All @@ -1336,8 +1337,9 @@ describe('ReactDOMInput', () => {
expect(() =>
ReactDOM.render(<input type="text" value="controlled" />, container),
).toErrorDev(
'Warning: A component is changing an uncontrolled input of type text to be controlled. ' +
'Input elements should not switch from uncontrolled to controlled (or vice versa). ' +
'Warning: A component is changing an uncontrolled input to be controlled. ' +
'This is likely caused by the value changing from undefined to ' +
'a defined value, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components\n' +
' in input (at **)',
Expand All @@ -1352,8 +1354,9 @@ describe('ReactDOMInput', () => {
expect(() =>
ReactDOM.render(<input type="checkbox" />, container),
).toErrorDev(
'Warning: A component is changing a controlled input of type checkbox to be uncontrolled. ' +
'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
'Warning: A component is changing a controlled input to be uncontrolled. ' +
'This is likely caused by the value changing from a defined to ' +
'undefined, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components\n' +
' in input (at **)',
Expand All @@ -1368,8 +1371,9 @@ describe('ReactDOMInput', () => {
expect(() =>
ReactDOM.render(<input type="checkbox" checked={null} />, container),
).toErrorDev(
'Warning: A component is changing a controlled input of type checkbox to be uncontrolled. ' +
'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
'Warning: A component is changing a controlled input to be uncontrolled. ' +
'This is likely caused by the value changing from a defined to ' +
'undefined, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components\n' +
' in input (at **)',
Expand All @@ -1387,8 +1391,9 @@ describe('ReactDOMInput', () => {
container,
),
).toErrorDev(
'Warning: A component is changing a controlled input of type checkbox to be uncontrolled. ' +
'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
'Warning: A component is changing a controlled input to be uncontrolled. ' +
'This is likely caused by the value changing from a defined to ' +
'undefined, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components\n' +
' in input (at **)',
Expand All @@ -1401,8 +1406,9 @@ describe('ReactDOMInput', () => {
expect(() =>
ReactDOM.render(<input type="checkbox" checked={true} />, container),
).toErrorDev(
'Warning: A component is changing an uncontrolled input of type checkbox to be controlled. ' +
'Input elements should not switch from uncontrolled to controlled (or vice versa). ' +
'Warning: A component is changing an uncontrolled input to be controlled. ' +
'This is likely caused by the value changing from undefined to ' +
'a defined value, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components\n' +
' in input (at **)',
Expand All @@ -1415,8 +1421,9 @@ describe('ReactDOMInput', () => {
expect(() =>
ReactDOM.render(<input type="checkbox" checked={true} />, container),
).toErrorDev(
'Warning: A component is changing an uncontrolled input of type checkbox to be controlled. ' +
'Input elements should not switch from uncontrolled to controlled (or vice versa). ' +
'Warning: A component is changing an uncontrolled input to be controlled. ' +
'This is likely caused by the value changing from undefined to ' +
'a defined value, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components\n' +
' in input (at **)',
Expand All @@ -1427,8 +1434,9 @@ describe('ReactDOMInput', () => {
const stub = <input type="radio" checked={true} onChange={emptyFunction} />;
ReactDOM.render(stub, container);
expect(() => ReactDOM.render(<input type="radio" />, container)).toErrorDev(
'Warning: A component is changing a controlled input of type radio to be uncontrolled. ' +
'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
'Warning: A component is changing a controlled input to be uncontrolled. ' +
'This is likely caused by the value changing from a defined to ' +
'undefined, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components\n' +
' in input (at **)',
Expand All @@ -1441,8 +1449,9 @@ describe('ReactDOMInput', () => {
expect(() =>
ReactDOM.render(<input type="radio" checked={null} />, container),
).toErrorDev(
'Warning: A component is changing a controlled input of type radio to be uncontrolled. ' +
'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
'Warning: A component is changing a controlled input to be uncontrolled. ' +
'This is likely caused by the value changing from a defined to ' +
'undefined, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components\n' +
' in input (at **)',
Expand All @@ -1455,8 +1464,9 @@ describe('ReactDOMInput', () => {
expect(() =>
ReactDOM.render(<input type="radio" defaultChecked={true} />, container),
).toErrorDev(
'Warning: A component is changing a controlled input of type radio to be uncontrolled. ' +
'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
'Warning: A component is changing a controlled input to be uncontrolled. ' +
'This is likely caused by the value changing from a defined to ' +
'undefined, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components\n' +
' in input (at **)',
Expand All @@ -1469,8 +1479,9 @@ describe('ReactDOMInput', () => {
expect(() =>
ReactDOM.render(<input type="radio" checked={true} />, container),
).toErrorDev(
'Warning: A component is changing an uncontrolled input of type radio to be controlled. ' +
'Input elements should not switch from uncontrolled to controlled (or vice versa). ' +
'Warning: A component is changing an uncontrolled input to be controlled. ' +
'This is likely caused by the value changing from undefined to ' +
'a defined value, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components\n' +
' in input (at **)',
Expand All @@ -1483,8 +1494,9 @@ describe('ReactDOMInput', () => {
expect(() =>
ReactDOM.render(<input type="radio" checked={true} />, container),
).toErrorDev(
'Warning: A component is changing an uncontrolled input of type radio to be controlled. ' +
'Input elements should not switch from uncontrolled to controlled (or vice versa). ' +
'Warning: A component is changing an uncontrolled input to be controlled. ' +
'This is likely caused by the value changing from undefined to ' +
'a defined value, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components\n' +
' in input (at **)',
Expand Down Expand Up @@ -1535,8 +1547,9 @@ describe('ReactDOMInput', () => {
expect(() =>
ReactDOM.render(<input type="radio" value="value" />, container),
).toErrorDev(
'Warning: A component is changing a controlled input of type radio to be uncontrolled. ' +
'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
'Warning: A component is changing a controlled input to be uncontrolled. ' +
'This is likely caused by the value changing from a defined to ' +
'undefined, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components\n' +
' in input (at **)',
Expand Down Expand Up @@ -1817,8 +1830,7 @@ describe('ReactDOMInput', () => {

it('reverts the value attribute to the initial value', () => {
expect(renderInputWithStringThenWithUndefined).toErrorDev(
'Input elements should not switch from controlled to ' +
'uncontrolled (or vice versa).',
'A component is changing a controlled input to be uncontrolled.',
);
if (disableInputAttributeSyncing) {
expect(input.getAttribute('value')).toBe(null);
Expand All @@ -1829,8 +1841,7 @@ describe('ReactDOMInput', () => {

it('preserves the value property', () => {
expect(renderInputWithStringThenWithUndefined).toErrorDev(
'Input elements should not switch from controlled to ' +
'uncontrolled (or vice versa).',
'A component is changing a controlled input to be uncontrolled.',
);
expect(input.value).toBe('latest');
});
Expand Down Expand Up @@ -1869,8 +1880,7 @@ describe('ReactDOMInput', () => {
'`value` prop on `input` should not be null. ' +
'Consider using an empty string to clear the component ' +
'or `undefined` for uncontrolled components.',
'Input elements should not switch from controlled ' +
'to uncontrolled (or vice versa).',
'A component is changing a controlled input to be uncontrolled.',
]);
if (disableInputAttributeSyncing) {
expect(input.hasAttribute('value')).toBe(false);
Expand All @@ -1884,8 +1894,7 @@ describe('ReactDOMInput', () => {
'`value` prop on `input` should not be null. ' +
'Consider using an empty string to clear the component ' +
'or `undefined` for uncontrolled components.',
'Input elements should not switch from controlled ' +
'to uncontrolled (or vice versa).',
'A component is changing a controlled input to be uncontrolled.',
]);
expect(input.value).toBe('latest');
});
Expand Down
12 changes: 6 additions & 6 deletions packages/react-dom/src/client/ReactDOMInput.js
Expand Up @@ -141,11 +141,11 @@ export function updateWrapper(element: Element, props: Object) {
!didWarnUncontrolledToControlled
) {
console.error(
'A component is changing an uncontrolled input of type %s to be controlled. ' +
'Input elements should not switch from uncontrolled to controlled (or vice versa). ' +
'A component is changing an uncontrolled input to be controlled. ' +
'This is likely caused by the value changing from undefined to ' +
'a defined value, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components',
props.type,
);
didWarnUncontrolledToControlled = true;
}
Expand All @@ -155,11 +155,11 @@ export function updateWrapper(element: Element, props: Object) {
!didWarnControlledToUncontrolled
) {
console.error(
'A component is changing a controlled input of type %s to be uncontrolled. ' +
'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
'A component is changing a controlled input to be uncontrolled. ' +
'This is likely caused by the value changing from a defined to ' +
'undefined, which should not happen. ' +
'Decide between using a controlled or uncontrolled input ' +
'element for the lifetime of the component. More info: https://fb.me/react-controlled-components',
props.type,
);
didWarnControlledToUncontrolled = true;
}
Expand Down