UNPKG

4.6 kBJavaScriptView Raw
1import { warn } from './warn';
2import { isControlled as checkIsControlled } from '../controlled';
3var warningsMap;
4if (process.env.NODE_ENV !== 'production') {
5 warningsMap = {
6 valueOnChange: {},
7 valueDefaultValue: {},
8 controlledToUncontrolled: {},
9 uncontrolledToControlled: {},
10 };
11}
12/** Reset controlled usage warnings for testing purposes. */
13export function resetControlledWarnings() {
14 if (process.env.NODE_ENV !== 'production') {
15 warningsMap.valueOnChange = {};
16 warningsMap.valueDefaultValue = {};
17 warningsMap.controlledToUncontrolled = {};
18 warningsMap.uncontrolledToControlled = {};
19 }
20}
21/**
22 * Check for and warn on the following error conditions with a form component:
23 * - A value prop is provided (indicated it's being used as controlled) without a change handler,
24 * and the component is not read-only
25 * - Both the value and defaultValue props are provided
26 * - The component is attempting to switch between controlled and uncontrolled
27 *
28 * The messages mimic the warnings React gives for these error conditions on input elements.
29 * The warning will only be displayed once per component ID.
30 */
31export function warnControlledUsage(params) {
32 if (process.env.NODE_ENV !== 'production') {
33 var componentId = params.componentId, componentName = params.componentName, defaultValueProp = params.defaultValueProp, props = params.props, oldProps = params.oldProps, onChangeProp = params.onChangeProp, readOnlyProp = params.readOnlyProp, valueProp = params.valueProp;
34 // This warning logic closely follows what React does for native <input> elements.
35 var oldIsControlled = oldProps ? checkIsControlled(oldProps, valueProp) : undefined;
36 var newIsControlled = checkIsControlled(props, valueProp);
37 if (newIsControlled) {
38 // onChange (or readOnly) must be provided if value is provided
39 var hasOnChange = !!props[onChangeProp];
40 var isReadOnly = !!(readOnlyProp && props[readOnlyProp]);
41 if (!(hasOnChange || isReadOnly) && !warningsMap.valueOnChange[componentId]) {
42 warningsMap.valueOnChange[componentId] = true;
43 warn("Warning: You provided a '" + valueProp + "' prop to a " + componentName + " without an '" + onChangeProp + "' handler. " +
44 ("This will render a read-only field. If the field should be mutable use '" + defaultValueProp + "'. ") +
45 ("Otherwise, set '" + onChangeProp + "'" + (readOnlyProp ? " or '" + readOnlyProp + "'" : '') + "."));
46 }
47 // value and defaultValue are mutually exclusive
48 var defaultValue = props[defaultValueProp];
49 if (defaultValue !== undefined && defaultValue !== null && !warningsMap.valueDefaultValue[componentId]) {
50 warningsMap.valueDefaultValue[componentId] = true;
51 warn("Warning: You provided both '" + valueProp + "' and '" + defaultValueProp + "' to a " + componentName + ". " +
52 ("Form fields must be either controlled or uncontrolled (specify either the '" + valueProp + "' prop, ") +
53 ("or the '" + defaultValueProp + "' prop, but not both). Decide between using a controlled or uncontrolled ") +
54 (componentName + " and remove one of these props. More info: https://fb.me/react-controlled-components"));
55 }
56 }
57 // Warn if switching between uncontrolled and controlled. (One difference between this implementation
58 // and React's <input> is that if oldIsControlled is indeterminate and newIsControlled true, we don't warn.)
59 if (oldProps && newIsControlled !== oldIsControlled) {
60 var oldType = oldIsControlled ? 'a controlled' : 'an uncontrolled';
61 var newType = oldIsControlled ? 'uncontrolled' : 'controlled';
62 var warnMap = oldIsControlled ? warningsMap.controlledToUncontrolled : warningsMap.uncontrolledToControlled;
63 if (!warnMap[componentId]) {
64 warnMap[componentId] = true;
65 warn("Warning: A component is changing " + oldType + " " + componentName + " to be " + newType + ". " +
66 (componentName + "s should not switch from controlled to uncontrolled (or vice versa). ") +
67 "Decide between using controlled or uncontrolled for the lifetime of the component. " +
68 "More info: https://fb.me/react-controlled-components");
69 }
70 }
71 }
72}
73//# sourceMappingURL=warnControlledUsage.js.map
\No newline at end of file