Warn if input changes controlledness - also for null (#7544) (#7603)
Marcin Mazurek committed
Aug 29, 2016 at 19:23 UTC
ba84b5b0a7047115e60a8fc68d563782a5756fba
2 files changed
+91
-7
src/renderers/dom/client/wrappers/ReactDOMInput.js
+1
-1
@@ -36,7 +36,7 @@ function forceUpdateIfMounted() {
36
37
function isControlled(props) {
38
var usesChecked = props.type === 'checkbox' || props.type === 'radio';
39
- return usesChecked ? props.checked !== undefined : props.value !== undefined;
39
+ return usesChecked ? props.checked != null : props.value != null;
40
}
41
42
/**
src/renderers/dom/client/wrappers/__tests__/ReactDOMInput-test.js
+90
-6
@@ -580,7 +580,7 @@ describe('ReactDOMInput', function() {
580
expect(console.error.calls.count()).toBe(1);
581
});
582
583
- it('should warn if controlled input switches to uncontrolled', function() {
583
+ it('should warn if controlled input switches to uncontrolled (value is undefined)', function() {
584
var stub = <input type="text" value="controlled" onChange={emptyFunction} />;
585
var container = document.createElement('div');
586
ReactDOM.render(stub, container);
@@ -594,6 +594,20 @@ describe('ReactDOMInput', function() {
594
);
595
});
596
597
+ it('should warn if controlled input switches to uncontrolled (value is null)', function() {
598
+ var stub = <input type="text" value="controlled" onChange={emptyFunction} />;
599
+ var container = document.createElement('div');
600
+ ReactDOM.render(stub, container);
601
+ ReactDOM.render(<input type="text" value={null} />, container);
602
+ expect(console.error.calls.count()).toBeGreaterThan(0);
603
+ expect(console.error.calls.argsFor(1)[0]).toContain(
604
+ 'A component is changing a controlled input of type text to be uncontrolled. ' +
605
+ 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
606
+ 'Decide between using a controlled or uncontrolled input ' +
607
+ 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components'
608
+ );
609
+ });
610
+
611
it('should warn if controlled input switches to uncontrolled with defaultValue', function() {
612
var stub = <input type="text" value="controlled" onChange={emptyFunction} />;
613
var container = document.createElement('div');
@@ -608,7 +622,7 @@ describe('ReactDOMInput', function() {
622
);
623
});
624
611
- it('should warn if uncontrolled input switches to controlled', function() {
625
+ it('should warn if uncontrolled input (value is undefined) switches to controlled', function() {
626
var stub = <input type="text" />;
627
var container = document.createElement('div');
628
ReactDOM.render(stub, container);
@@ -622,7 +636,21 @@ describe('ReactDOMInput', function() {
636
);
637
});
638
625
- it('should warn if controlled checkbox switches to uncontrolled', function() {
639
+ it('should warn if uncontrolled input (value is null) switches to controlled', function() {
640
+ var stub = <input type="text" value={null} />;
641
+ var container = document.createElement('div');
642
+ ReactDOM.render(stub, container);
643
+ ReactDOM.render(<input type="text" value="controlled" />, container);
644
+ expect(console.error.calls.count()).toBeGreaterThan(0);
645
+ expect(console.error.calls.argsFor(1)[0]).toContain(
646
+ 'A component is changing an uncontrolled input of type text to be controlled. ' +
647
+ 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' +
648
+ 'Decide between using a controlled or uncontrolled input ' +
649
+ 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components'
650
+ );
651
+ });
652
+
653
+ it('should warn if controlled checkbox switches to uncontrolled (checked is undefined)', function() {
654
var stub = <input type="checkbox" checked={true} onChange={emptyFunction} />;
655
var container = document.createElement('div');
656
ReactDOM.render(stub, container);
@@ -636,6 +664,20 @@ describe('ReactDOMInput', function() {
664
);
665
});
666
667
+ it('should warn if controlled checkbox switches to uncontrolled (checked is null)', function() {
668
+ var stub = <input type="checkbox" checked={true} onChange={emptyFunction} />;
669
+ var container = document.createElement('div');
670
+ ReactDOM.render(stub, container);
671
+ ReactDOM.render(<input type="checkbox" checked={null} />, container);
672
+ expect(console.error.calls.count()).toBe(1);
673
+ expect(console.error.calls.argsFor(0)[0]).toContain(
674
+ 'A component is changing a controlled input of type checkbox to be uncontrolled. ' +
675
+ 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
676
+ 'Decide between using a controlled or uncontrolled input ' +
677
+ 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components'
678
+ );
679
+ });
680
+
681
it('should warn if controlled checkbox switches to uncontrolled with defaultChecked', function() {
682
var stub = <input type="checkbox" checked={true} onChange={emptyFunction} />;
683
var container = document.createElement('div');
@@ -650,7 +692,7 @@ describe('ReactDOMInput', function() {
692
);
693
});
694
653
- it('should warn if uncontrolled checkbox switches to controlled', function() {
695
+ it('should warn if uncontrolled checkbox (checked is undefined) switches to controlled', function() {
696
var stub = <input type="checkbox" />;
697
var container = document.createElement('div');
698
ReactDOM.render(stub, container);
@@ -664,7 +706,21 @@ describe('ReactDOMInput', function() {
706
);
707
});
708
667
- it('should warn if controlled radio switches to uncontrolled', function() {
709
+ it('should warn if uncontrolled checkbox (checked is null) switches to controlled', function() {
710
+ var stub = <input type="checkbox" checked={null} />;
711
+ var container = document.createElement('div');
712
+ ReactDOM.render(stub, container);
713
+ ReactDOM.render(<input type="checkbox" checked={true} />, container);
714
+ expect(console.error.calls.count()).toBe(1);
715
+ expect(console.error.calls.argsFor(0)[0]).toContain(
716
+ 'A component is changing an uncontrolled input of type checkbox to be controlled. ' +
717
+ 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' +
718
+ 'Decide between using a controlled or uncontrolled input ' +
719
+ 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components'
720
+ );
721
+ });
722
+
723
+ it('should warn if controlled radio switches to uncontrolled (checked is undefined)', function() {
724
var stub = <input type="radio" checked={true} onChange={emptyFunction} />;
725
var container = document.createElement('div');
726
ReactDOM.render(stub, container);
@@ -678,6 +734,20 @@ describe('ReactDOMInput', function() {
734
);
735
});
736
737
+ it('should warn if controlled radio switches to uncontrolled (checked is null)', function() {
738
+ var stub = <input type="radio" checked={true} onChange={emptyFunction} />;
739
+ var container = document.createElement('div');
740
+ ReactDOM.render(stub, container);
741
+ ReactDOM.render(<input type="radio" checked={null} />, container);
742
+ expect(console.error.calls.count()).toBe(1);
743
+ expect(console.error.calls.argsFor(0)[0]).toContain(
744
+ 'A component is changing a controlled input of type radio to be uncontrolled. ' +
745
+ 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
746
+ 'Decide between using a controlled or uncontrolled input ' +
747
+ 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components'
748
+ );
749
+ });
750
+
751
it('should warn if controlled radio switches to uncontrolled with defaultChecked', function() {
752
var stub = <input type="radio" checked={true} onChange={emptyFunction} />;
753
var container = document.createElement('div');
@@ -692,7 +762,7 @@ describe('ReactDOMInput', function() {
762
);
763
});
764
695
- it('should warn if uncontrolled radio switches to controlled', function() {
765
+ it('should warn if uncontrolled radio (checked is undefined) switches to controlled', function() {
766
var stub = <input type="radio" />;
767
var container = document.createElement('div');
768
ReactDOM.render(stub, container);
@@ -706,6 +776,20 @@ describe('ReactDOMInput', function() {
776
);
777
});
778
779
+ it('should warn if uncontrolled radio (checked is null) switches to controlled', function() {
780
+ var stub = <input type="radio" checked={null} />;
781
+ var container = document.createElement('div');
782
+ ReactDOM.render(stub, container);
783
+ ReactDOM.render(<input type="radio" checked={true} />, container);
784
+ expect(console.error.calls.count()).toBe(1);
785
+ expect(console.error.calls.argsFor(0)[0]).toContain(
786
+ 'A component is changing an uncontrolled input of type radio to be controlled. ' +
787
+ 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' +
788
+ 'Decide between using a controlled or uncontrolled input ' +
789
+ 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components'
790
+ );
791
+ });
792
+
793
it('should not warn if radio value changes but never becomes controlled', function() {
794
var container = document.createElement('div');
795
ReactDOM.render(<input type="radio" value="value" />, container);