Warn for common forms misuse
Pete Hunt committed
Jan 7, 2014 at 19:03 UTC
b1597ab2d73d6d73e69b26e611601f0b4955b3ab
2 files changed
+50
src/dom/components/LinkedValueMixin.js
+15
@@ -26,6 +26,21 @@ var invariant = require('invariant');
26
* this outside of the ReactDOM controlled form components.
27
*/
28
var LinkedValueMixin = {
29
+ propTypes: {
30
+ value: function(props, propName, componentName) {
31
+ if (__DEV__) {
32
+ if (props[propName] && !props.onChange && !props.readOnly) {
33
+ console.warn(
34
+ 'You provided a `value` prop to a form field without an ' +
35
+ '`onChange` handler. This will render a read-only field. If ' +
36
+ 'the field should be mutable use `defaultValue`. Otherwise, set ' +
37
+ 'either `onChange` or `readOnly`. '
38
+ );
39
+ }
40
+ }
41
+ }
42
+ },
43
+
44
_assertLink: function() {
45
invariant(
46
this.props.value == null && this.props.onChange == null,
src/dom/components/__tests__/ReactDOMInput-test.js
+35
@@ -198,6 +198,41 @@ describe('ReactDOMInput', function() {
198
expect(link.requestChange.mock.calls[0][0]).toEqual('test');
199
});
200
201
+ it('should warn with value and no onChange handler', function() {
202
+ var oldWarn = console.warn;
203
+ try {
204
+ console.warn = mocks.getMockFunction();
205
+
206
+ var node = document.createElement('div');
207
+ var link = new ReactLink('yolo', mocks.getMockFunction());
208
+ React.renderComponent(<input type="text" valueLink={link} />, node);
209
+ expect(console.warn.mock.calls.length).toBe(0);
210
+
211
+ React.renderComponent(
212
+ <input type="text" value="zoink" onChange={mocks.getMockFunction()} />,
213
+ node
214
+ );
215
+ expect(console.warn.mock.calls.length).toBe(0);
216
+
217
+ React.renderComponent(
218
+ <input type="text" value="zoink" readOnly={true} />,
219
+ node
220
+ );
221
+ expect(console.warn.mock.calls.length).toBe(0);
222
+
223
+ React.renderComponent(<input type="text" value="zoink" />, node);
224
+ expect(console.warn.mock.calls.length).toBe(1);
225
+
226
+ React.renderComponent(
227
+ <input type="text" value="zoink" readOnly={false} />,
228
+ node
229
+ );
230
+ expect(console.warn.mock.calls.length).toBe(2);
231
+ } finally {
232
+ console.warn = oldWarn;
233
+ }
234
+ });
235
+
236
it('should throw if both value and valueLink are provided', function() {
237
// Silences console.error messages
238
// ReactErrorUtils.guard is applied to all methods of a React component