1414
assertInputTrackingIsCurrent(container);
1415
});
1416
1417
+ it('should control radio buttons if the tree updates during render (case 2; #26876)', () => {
1418
+ let thunk = null;
1419
+ function App() {
1420
+ const [disabled, setDisabled] = React.useState(false);
1421
+ const [value, setValue] = React.useState('one');
1422
+ function handleChange(e) {
1423
+ setDisabled(true);
1424
+ // Pretend this is in a setTimeout or something
1425
+ thunk = () => {
1426
+ setDisabled(false);
1427
+ setValue(e.target.value);
1428
+ };
1429
+ }
1430
+ return (
1431
+ <>
1432
+ <input
1433
+ type="radio"
1434
+ name="fruit"
1435
+ value="one"
1436
+ checked={value === 'one'}
1437
+ onChange={handleChange}
1438
+ disabled={disabled}
1439
+ />
1440
+ <input
1441
+ type="radio"
1442
+ name="fruit"
1443
+ value="two"
1444
+ checked={value === 'two'}
1445
+ onChange={handleChange}
1446
+ disabled={disabled}
1447
+ />
1448
+ </>
1449
+ );
1450
+ }
1451
+ ReactDOM.render(<App />, container);
1452
+ const [one, two] = container.querySelectorAll('input');
1453
+ expect(one.checked).toBe(true);
1454
+ expect(two.checked).toBe(false);
1455
+ expect(isCheckedDirty(one)).toBe(true);
1456
+ expect(isCheckedDirty(two)).toBe(true);
1457
+ assertInputTrackingIsCurrent(container);
1458
+
1459
+ // Click two
1460
+ setUntrackedChecked.call(two, true);
1461
+ dispatchEventOnNode(two, 'click');
1462
+ expect(one.checked).toBe(true);
1463
+ expect(two.checked).toBe(false);
1464
+ expect(isCheckedDirty(one)).toBe(true);
1465
+ expect(isCheckedDirty(two)).toBe(true);
1466
+ assertInputTrackingIsCurrent(container);
1467
+
1468
+ // After a delay...
1469
+ ReactDOM.unstable_batchedUpdates(thunk);
1470
+ expect(one.checked).toBe(false);
1471
+ expect(two.checked).toBe(true);
1472
+ expect(isCheckedDirty(one)).toBe(true);
1473
+ expect(isCheckedDirty(two)).toBe(true);
1474
+ assertInputTrackingIsCurrent(container);
1475
+
1476
+ // Click back to one
1477
+ setUntrackedChecked.call(one, true);
1478
+ dispatchEventOnNode(one, 'click');
1479
+ expect(one.checked).toBe(false);
1480
+ expect(two.checked).toBe(true);
1481
+ expect(isCheckedDirty(one)).toBe(true);
1482
+ expect(isCheckedDirty(two)).toBe(true);
1483
+ assertInputTrackingIsCurrent(container);
1484
+
1485
+ // After a delay...
1486
+ ReactDOM.unstable_batchedUpdates(thunk);
1487
+ expect(one.checked).toBe(true);
1488
+ expect(two.checked).toBe(false);
1489
+ expect(isCheckedDirty(one)).toBe(true);
1490
+ expect(isCheckedDirty(two)).toBe(true);
1491
+ assertInputTrackingIsCurrent(container);
1492
+ });
1493
+
1494
it('should warn with value and no onChange handler and readOnly specified', () => {
1495
ReactDOM.render(
1496
<input type="text" value="zoink" readOnly={true} />,