Skip to content

Commit bcd9c9f

Browse files
authored
feat/useToggleValue (#1019)
* Replace unsafe method with getDerivedStateFromProps * added testing-library support for hooks unit tests * add useToggleValue to easily replace useState of two value, works as toggle between any two values * export useToggleValue hook * fix test wrong import * introduce Hooks type, contains useToggleValue custom hook
1 parent 0375ae5 commit bcd9c9f

File tree

11 files changed

+126
-1
lines changed

11 files changed

+126
-1
lines changed

generatedTypes/commons/new.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ export { default as asBaseComponent, BaseComponentInjectedProps } from './asBase
33
export { default as forwardRef, ForwardRefInjectedProps } from './forwardRef';
44
export { default as withScrollEnabler, WithScrollEnablerProps } from './withScrollEnabler';
55
export { default as withScrollReached, WithScrollReachedProps } from './withScrollReached';
6+
export { default as useToggleValue } from './useToggleValue';
67
export { ContainerModifiers, MarginModifiers, PaddingModifiers, TypographyModifiers, ColorsModifiers, BackgroundColorModifier } from './modifiers';
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
declare const useToggleValue: (initial: any, second?: any) => any[];
2+
export default useToggleValue;

generatedTypes/index.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
export * from './style';
77
export * from './services';
88
export * as Incubator from './incubator';
9+
export * as Hooks from './hooks';
910
export {
1011
asBaseComponent,
1112
withScrollEnabler,
@@ -19,7 +20,8 @@ export {
1920
PaddingModifiers,
2021
TypographyModifiers,
2122
ColorsModifiers,
22-
BackgroundColorModifier
23+
BackgroundColorModifier,
24+
useToggleValue
2325
} from './commons/new';
2426
export {default as ActionBar, ActionBarProps} from './components/actionBar';
2527
export {default as Avatar, AvatarPropTypes} from './components/avatar';

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"@react-native-community/eslint-config": "^1.1.0",
7070
"@react-native-community/netinfo": "^5.6.2",
7171
"@react-native-community/picker": "^1.6.5",
72+
"@testing-library/react-hooks": "^3.4.2",
7273
"@types/lodash": "^4.0.0",
7374
"@types/prop-types": "^15.5.3",
7475
"@types/react-native": "0.62.2",

src/commons/new.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export {default as asBaseComponent, BaseComponentInjectedProps} from './asBaseCo
44
export {default as forwardRef, ForwardRefInjectedProps} from './forwardRef';
55
export {default as withScrollEnabler, WithScrollEnablerProps} from './withScrollEnabler';
66
export {default as withScrollReached, WithScrollReachedProps} from './withScrollReached';
7+
78
export {
89
ContainerModifiers,
910
MarginModifiers,

src/hooks/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {default as useToggleValue} from './useToggleValue';
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import {renderHook, act} from '@testing-library/react-hooks';
2+
import useToggleValue from '../index';
3+
4+
describe('useOrientation hook tests', () => {
5+
const makeSUT = (initial, secondary) => {
6+
return renderHook(() => {
7+
return useToggleValue(initial, secondary);
8+
});
9+
};
10+
11+
const getValue = (result) => {
12+
return result.current[0];
13+
};
14+
15+
const getToggle = (result) => {
16+
return result.current[1]();
17+
};
18+
19+
const expectValueToToggle = (a, b) => {
20+
const {result} = makeSUT(a, b);
21+
expect(getValue(result)).toEqual(a);
22+
23+
act(() => getToggle(result));
24+
expect(getValue(result)).toEqual(b);
25+
};
26+
27+
it('Initial value should be set', () => {
28+
const {result} = makeSUT(true, false);
29+
30+
expect(getValue(result)).toEqual(true);
31+
});
32+
33+
it('Initial value can be undefined', () => {
34+
const {result} = makeSUT(undefined, 'Sid');
35+
expect(getValue(result)).toEqual(undefined);
36+
37+
act(() => getToggle(result));
38+
expect(getValue(result)).toEqual('Sid');
39+
});
40+
41+
it('Initial value can be change', () => {
42+
const {result} = makeSUT(true, false);
43+
act(() => getToggle(result));
44+
45+
expect(getValue(result)).toEqual(false);
46+
});
47+
48+
it('Allow toggle boolean without passing a second parameter', () => {
49+
const {result} = makeSUT(true);
50+
act(() => getToggle(result));
51+
52+
expect(getValue(result)).toEqual(false);
53+
});
54+
55+
it('Can toggle strings', () => {
56+
const a = 'Ohio';
57+
const b = 'Texas';
58+
59+
expectValueToToggle(a, b);
60+
});
61+
62+
it('Can toggle numbers', () => {
63+
const a = 30;
64+
const b = 22;
65+
66+
expectValueToToggle(a, b);
67+
});
68+
69+
it('Can toggle arrays', () => {
70+
const a = [1, 2, 3, 4];
71+
const b = ['Booking', 'OneApp', 'Fed'];
72+
73+
expectValueToToggle(a, b);
74+
});
75+
76+
it('Can toggle objects', () => {
77+
const a = {};
78+
const b = {name: 'Darth', occupation: 'Father'};
79+
80+
expectValueToToggle(a, b);
81+
});
82+
83+
it('Can toggle different types', () => {
84+
const a = 999;
85+
const b = '999';
86+
87+
expectValueToToggle(a, b);
88+
});
89+
});

src/hooks/useToggleValue/index.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import {useState, useRef} from 'react';
2+
import _ from 'lodash';
3+
4+
const useToggleValue = (initial: any, second?: any) => {
5+
const initialValue = useRef(initial).current;
6+
const secondValue = useRef(second).current;
7+
8+
const [value, setValue] = useState(initial);
9+
10+
const toggle = () => {
11+
if (_.isBoolean(initialValue)) {
12+
setValue(!initialValue);
13+
} else if (value == initialValue) {
14+
setValue(secondValue);
15+
} else {
16+
setValue(initialValue);
17+
}
18+
};
19+
20+
return [value, toggle, setValue];
21+
};
22+
23+
export default useToggleValue;

src/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,9 @@ export default {
291291
get AnimatableManager() {
292292
return require('./style').AnimatableManager;
293293
},
294+
get Hooks() {
295+
return require('./hooks');
296+
},
294297

295298
// Incubator
296299
get Incubator() {

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export {
1717
BackgroundColorModifier
1818
} from './commons/new';
1919
export * as Incubator from './incubator';
20+
export * as Hooks from './hooks';
2021
export {default as ActionBar, ActionBarProps} from './components/actionBar';
2122
export {default as Avatar, AvatarPropTypes} from './components/avatar';
2223
export {default as Badge, BadgeProps} from './components/badge';

typings/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ export * from './nativeComponents';
99
export * from './services';
1010
export * from './generatedTypes';
1111
export * from './globalTypes';
12+
export * from './hooks';

0 commit comments

Comments
 (0)