Skip to content

Commit 94ba8af

Browse files
authored
Merge branch 'react-component:master' into master
2 parents 5397b78 + 43394c4 commit 94ba8af

File tree

6 files changed

+109
-20
lines changed

6 files changed

+109
-20
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "rc-util",
3-
"version": "5.32.2",
3+
"version": "5.34.1",
44
"description": "Common Utils For React Component",
55
"keywords": [
66
"react",

src/hooks/useLayoutEffect.ts

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,39 @@ import canUseDom from '../Dom/canUseDom';
44
/**
55
* Wrap `React.useLayoutEffect` which will not throw warning message in test env
66
*/
7-
const useLayoutEffect =
7+
const useInternalLayoutEffect =
88
process.env.NODE_ENV !== 'test' && canUseDom()
99
? React.useLayoutEffect
1010
: React.useEffect;
1111

12-
export default useLayoutEffect;
13-
14-
export const useLayoutUpdateEffect: typeof React.useEffect = (
15-
callback,
16-
deps,
12+
const useLayoutEffect = (
13+
callback: (mount: boolean) => void | VoidFunction,
14+
deps?: React.DependencyList,
1715
) => {
1816
const firstMountRef = React.useRef(true);
1917

20-
useLayoutEffect(() => {
21-
if (!firstMountRef.current) {
22-
return callback();
23-
}
18+
useInternalLayoutEffect(() => {
19+
return callback(firstMountRef.current);
2420
}, deps);
2521

2622
// We tell react that first mount has passed
27-
useLayoutEffect(() => {
23+
useInternalLayoutEffect(() => {
2824
firstMountRef.current = false;
2925
return () => {
3026
firstMountRef.current = true;
3127
};
3228
}, []);
3329
};
30+
31+
export const useLayoutUpdateEffect: typeof React.useEffect = (
32+
callback,
33+
deps,
34+
) => {
35+
useLayoutEffect(firstMount => {
36+
if (!firstMount) {
37+
return callback();
38+
}
39+
}, deps);
40+
};
41+
42+
export default useLayoutEffect;

src/utils/get.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export default function get(
22
entity: any,
3-
path: (string | number)[] | readonly (string | number)[],
3+
path: (string | number | symbol)[] | readonly (string | number | symbol)[],
44
) {
55
let current = entity;
66

src/utils/set.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import get from './get';
22

3-
export type Path = (string | number)[];
3+
export type Path = (string | number | symbol)[];
44

55
function internalSet<Entity = any, Output = Entity, Value = any>(
66
entity: Entity,
@@ -35,7 +35,7 @@ function internalSet<Entity = any, Output = Entity, Value = any>(
3535

3636
export default function set<Entity = any, Output = Entity, Value = any>(
3737
entity: Entity,
38-
paths: (string | number)[],
38+
paths: Path,
3939
value: Value,
4040
removeIfUndefined: boolean = false,
4141
): Output {
@@ -64,16 +64,18 @@ function createEmpty<T>(source: T) {
6464
return (Array.isArray(source) ? [] : {}) as T;
6565
}
6666

67+
const keys = typeof Reflect === 'undefined' ? Object.keys : Reflect.ownKeys;
68+
6769
/**
6870
* Merge objects which will create
6971
*/
7072
export function merge<T extends object>(...sources: T[]) {
7173
let clone = createEmpty(sources[0]);
7274

73-
const loopSet = new Set<object>();
74-
7575
sources.forEach(src => {
76-
function internalMerge(path: Path) {
76+
function internalMerge(path: Path, parentLoopSet?: Set<object>) {
77+
const loopSet = new Set(parentLoopSet);
78+
7779
const value = get(src, path);
7880

7981
const isArr = Array.isArray(value);
@@ -93,8 +95,8 @@ export function merge<T extends object>(...sources: T[]) {
9395
clone = set(clone, path, createEmpty(value));
9496
}
9597

96-
Object.keys(value).forEach(key => {
97-
internalMerge([...path, key]);
98+
keys(value).forEach(key => {
99+
internalMerge([...path, key], loopSet);
98100
});
99101
}
100102
} else {

tests/hooks.test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,30 @@ describe('hooks', () => {
343343
expect(errorSpy).not.toHaveBeenCalled();
344344
errorSpy.mockRestore();
345345
});
346+
347+
it('can get mount state', () => {
348+
const Demo = () => {
349+
const timesRef = React.useRef(0);
350+
const [, forceUpdate] = React.useState(0);
351+
352+
useLayoutEffect(firstMount => {
353+
if (timesRef.current === 0) {
354+
expect(firstMount).toBeTruthy();
355+
forceUpdate(1);
356+
} else {
357+
expect(firstMount).toBeFalsy();
358+
forceUpdate(2);
359+
}
360+
361+
timesRef.current += 1;
362+
});
363+
364+
return <p>{timesRef.current}</p>;
365+
};
366+
367+
const { container } = render(<Demo />);
368+
expect(container.querySelector('p').textContent).toEqual('2');
369+
});
346370
});
347371

348372
describe('useState', () => {

tests/utils.test.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,60 @@ describe('utils', () => {
192192
selector: ['K1', 'K2'],
193193
});
194194
});
195+
196+
it('shallow copy', () => {
197+
const ori = {
198+
list: [{ a: 1 }, { a: 2 }],
199+
};
200+
201+
const cloneList = [...ori.list];
202+
cloneList[0] = {
203+
...cloneList[0],
204+
b: 3,
205+
};
206+
207+
const merged = merge(ori, { list: cloneList });
208+
209+
expect(merged).toEqual({
210+
list: [{ a: 1, b: 3 }, { a: 2 }],
211+
});
212+
});
213+
214+
it('skip class object', () => {
215+
class User {
216+
constructor(name, age) {
217+
this.name = name;
218+
this.age = age;
219+
}
220+
}
221+
222+
const user = new User('little', 2);
223+
224+
const merged = merge({}, { user }, {});
225+
226+
expect(merged.user).toBe(user);
227+
});
228+
229+
it('ref object', () => {
230+
const obj = { bamboo: 1 };
231+
232+
const merged = merge({}, { a: obj, b: obj }, {});
233+
234+
expect(merged).toEqual({
235+
a: obj,
236+
b: obj,
237+
});
238+
});
239+
240+
it('support Symbol', () => {
241+
const symbol = Symbol();
242+
243+
const merged = merge({}, { [symbol]: 1 });
244+
245+
expect(merged).toEqual({
246+
[symbol]: 1,
247+
});
248+
});
195249
});
196250
});
197251

0 commit comments

Comments
 (0)