Skip to content

Commit de9d860

Browse files
authored
fix: null can be a value (#459)
* init * refactor option list select logic * add test case * add compile ci
1 parent 76e8c13 commit de9d860

File tree

6 files changed

+59
-10
lines changed

6 files changed

+59
-10
lines changed

.circleci/config.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,24 @@ jobs:
2929
- node_modules
3030
key: v1-dependencies-{{ checksum "package.json" }}
3131
- run: npm test -- --coverage
32+
compile:
33+
docker:
34+
- image: circleci/node:latest
35+
steps:
36+
- checkout
37+
- restore_cache:
38+
keys:
39+
- v1-dependencies-{{ checksum "package.json" }}
40+
- run: npm install
41+
- save_cache:
42+
paths:
43+
- node_modules
44+
key: v1-dependencies-{{ checksum "package.json" }}
45+
- run: npm run compile
3246
workflows:
3347
version: 2
3448
build_and_test:
3549
jobs:
3650
- lint
3751
- test
52+
- compile

examples/single.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class Test extends React.Component {
7979
console.log('Scroll:', args);
8080
}}
8181
>
82+
<Option value={null}>不选择</Option>
8283
<Option value="01" text="jack" title="jack">
8384
<b
8485
style={{

src/OptionList.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ const OptionList: React.RefForwardingComponent<
143143

144144
// ========================== Values ==========================
145145
const onSelectValue = (value: RawValueType) => {
146-
if (value !== null) {
146+
if (value !== undefined) {
147147
onSelect(value, { selected: !values.has(value) });
148148
}
149149

@@ -187,7 +187,7 @@ const OptionList: React.RefForwardingComponent<
187187
if (item && !(item.data as OptionData).disabled) {
188188
onSelectValue((item.data as OptionData).value);
189189
} else {
190-
onSelectValue(null);
190+
onSelectValue(undefined);
191191
}
192192

193193
if (open) {

src/generate.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -378,8 +378,7 @@ export default function generateSelector<
378378
const [innerValue, setInnerValue] = React.useState<ValueType>(
379379
value || defaultValue,
380380
);
381-
const baseValue =
382-
value !== undefined && value !== null ? value : innerValue;
381+
const baseValue = value !== undefined ? value : innerValue;
383382

384383
// Should reset when controlled to be uncontrolled
385384
const prevValueRef = React.useRef(value);

src/utils/commonUtil.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,16 @@ export function toInnerValue(
2020
value: DefaultValueType,
2121
{ labelInValue, combobox }: { labelInValue: boolean; combobox: boolean },
2222
): RawValueType[] {
23-
if (value === undefined || value === null || (value === '' && combobox)) {
23+
if (value === undefined || (value === '' && combobox)) {
2424
return [];
2525
}
2626

2727
const values = Array.isArray(value) ? value : [value];
2828

2929
if (labelInValue) {
30-
return values.map(({ key, value: val }: LabelValueType) => (val !== undefined ? val : key));
30+
return (values as LabelValueType[]).map(
31+
({ key, value: val }: LabelValueType) => (val !== undefined ? val : key),
32+
);
3133
}
3234

3335
return values as RawValueType[];
@@ -56,7 +58,12 @@ export function toOuterValues<FOT extends FlattenOptionsType>(
5658

5759
if (labelInValue) {
5860
values = values.map(val =>
59-
getLabeledValue(val, { options, prevValue, labelInValue, optionLabelProp }),
61+
getLabeledValue(val, {
62+
options,
63+
prevValue,
64+
labelInValue,
65+
optionLabelProp,
66+
}),
6067
);
6168
}
6269

@@ -70,7 +77,11 @@ export function removeLastEnabledValue<
7077
const newValues = [...values];
7178

7279
let removeIndex: number;
73-
for (removeIndex = measureValues.length - 1; removeIndex >= 0; removeIndex -= 1) {
80+
for (
81+
removeIndex = measureValues.length - 1;
82+
removeIndex >= 0;
83+
removeIndex -= 1
84+
) {
7485
if (!measureValues[removeIndex].disabled) {
7586
break;
7687
}
@@ -90,7 +101,9 @@ export function removeLastEnabledValue<
90101
}
91102

92103
export const isClient =
93-
typeof window !== 'undefined' && window.document && window.document.documentElement;
104+
typeof window !== 'undefined' &&
105+
window.document &&
106+
window.document.documentElement;
94107

95108
/** Is client side and not jsdom */
96109
export const isBrowserClient = process.env.NODE_ENV !== 'test' && isClient;

tests/Select.test.tsx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1450,7 +1450,7 @@ describe('Select.Basic', () => {
14501450
});
14511451

14521452
describe('reset value to undefined should reset display value', () => {
1453-
[undefined, null].forEach(value => {
1453+
[undefined].forEach(value => {
14541454
it(`to ${value}`, () => {
14551455
const wrapper = mount(<Select value="light" />);
14561456
expect(wrapper.find('.rc-select-selection-item').text()).toEqual(
@@ -1525,4 +1525,25 @@ describe('Select.Basic', () => {
15251525
background: 'yellow',
15261526
});
15271527
});
1528+
1529+
it('`null` is a value', () => {
1530+
const onChange = jest.fn();
1531+
1532+
const wrapper = mount(
1533+
<Select onChange={onChange}>
1534+
<Option value={1}>1</Option>
1535+
<Option value={null}>No</Option>
1536+
</Select>,
1537+
);
1538+
1539+
toggleOpen(wrapper);
1540+
selectItem(wrapper, 0);
1541+
expect(onChange).toHaveBeenCalledWith(1, expect.anything());
1542+
expect(wrapper.find('.rc-select-selection-item').text()).toEqual('1');
1543+
1544+
toggleOpen(wrapper);
1545+
selectItem(wrapper, 1);
1546+
expect(onChange).toHaveBeenCalledWith(null, expect.anything());
1547+
expect(wrapper.find('.rc-select-selection-item').text()).toEqual('No');
1548+
});
15281549
});

0 commit comments

Comments
 (0)