NativeBase
NativeBase copied to clipboard
A warning thrown with jest
Description
There was a warning thrown as we ran test as following: TypeError: _reactNative.AppState.removeEventListener is not a function
CodeSandbox/Snack link
https://codesandbox.io/s/codesandbox-sse-example-forked-izm8zv?file=/sample.test.jsx
Steps to reproduce
- Visit the above codesanbox
- Run
yarn test
command then you will the see the warning
NativeBase Version
3.4.15
Platform
- [ ] Android
- [ ] CRA
- [X] Expo
- [ ] iOS
- [ ] Next
Other Platform
No response
Additional Information
No response
my stack trace for this issue
console.error
Warning: Internal React error: Attempted to capture a commit phase error inside a detached tree. This indicates a bug in React. Likely causes include deleting the same fiber more than once, committing an already-finished tree, or an inconsistent return pointer.
Error message:
TypeError: _reactNative.AppState.removeEventListener is not a function
at HybridProvider (/Users/xxx/node_modules/native-base/lib/commonjs/core/hybrid-overlay/HybridProvider.tsx:9:3)
at ResponsiveQueryProvider (/Users/xxx/node_modules/native-base/lib/commonjs/utils/useResponsiveQuery/ResponsiveQueryProvider.tsx:20:12)
at RNCSafeAreaProvider
at Component (/Users/xxx/node_modules/react-native/jest/mockNativeComponent.js:17:18)
at SafeAreaProvider (/Users/xxx/node_modules/react-native-safe-area-context/lib/commonjs/SafeAreaContext.tsx:35:3)
at Provider (/Users/xxx/node_modules/native-base/lib/commonjs/utils/createContext.tsx:9:13)
at NativeBaseProvider (/Users/xxx/node_modules/native-base/lib/commonjs/core/NativeBaseProvider.tsx:52:5)
at TestingNativeBaseProvider (/Users/xxx/tests/ui/TestingNativeBaseProvider.tsx:5:3)
Same issue when updating from version^3.4.12
to ^3.4.16
.
Hey everyone, Thanks for reporting the issue. We'll fix it.
Hey guys, I've created temporary patch for this issue:
File: /patches/native-base+3.4.16.patch
diff --git a/node_modules/native-base/lib/commonjs/core/color-mode/hooks.js b/node_modules/native-base/lib/commonjs/core/color-mode/hooks.js
index 8e28efe..68490c8 100644
--- a/node_modules/native-base/lib/commonjs/core/color-mode/hooks.js
+++ b/node_modules/native-base/lib/commonjs/core/color-mode/hooks.js
@@ -45,9 +45,9 @@ const useAppState = () => {
const subscription = _react.default.useMemo(() => ({
getCurrentValue: () => _reactNative.AppState.currentState,
subscribe: callback => {
- _reactNative.AppState.addEventListener('change', callback);
+ const sb = _reactNative.AppState.addEventListener('change', callback);
- return () => _reactNative.AppState.removeEventListener('change', callback);
+ return () => sb.remove()
}
}), []);
After next release, just delete this patch.
Any idea on witch version this fix will be introduced? The new version native-base 3.4.18 still dont fix this bug
Still getting this warning:
Warning: Internal React error: Attempted to capture a commit phase error inside a detached tree. This indicates a bug in React. Likely causes include deleting the same fiber more than once, committing an already-finished tree, or an inconsistent return pointer.
Error message:
TypeError: _reactNative.AppState.removeEventListener is not a function
in HybridProvider (created by NativeBaseProvider)
in ResponsiveQueryProvider (created by NativeBaseProvider)
in RNCSafeAreaProvider (created by SafeAreaProvider)
in SafeAreaProvider (created by NativeBaseProvider)
in NativeBaseConfigProviderProvider (created by NativeBaseProvider)
in NativeBaseProvider (created by CameraView)
in CameraView (created by SceneView)
in StaticContainer
in EnsureSingleNavigator (created by SceneView)
in SceneView (created by SceneView)
in RCTView (created by View)
in View (created by DebugContainer)
in DebugContainer (created by MaybeNestedStack)
in MaybeNestedStack (created by SceneView)
in RNSScreen (created by AnimatedComponent)
in AnimatedComponent
in AnimatedComponentWrapper (created by InnerScreen)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by InnerScreen)
in InnerScreen (created by Screen)
in Screen (created by SceneView)
in SceneView (created by NativeStackViewInner)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by ScreenStack)
Getting the same error here when running tests with Jest
`console.error Warning: Internal React error: Attempted to capture a commit phase error inside a detached tree. This indicates a bug in React. Likely causes include deleting the same fiber more than once, committing an already-finished tree, or an inconsistent return pointer.
Error message:
TypeError: _reactNative.AppState.removeEventListener is not a function
at children (\node_modules\native-base\lib\commonjs\core\hybrid-overlay\HybridProvider.tsx:9:3)
at disableCSSMediaQueries (node_modules\native-base\lib\commonjs\utils\useResponsiveQuery\ResponsiveQueryProvider.tsx:20:12)
at RNCSafeAreaProvider
at RNCSafeAreaProvider (node_modules\react-native\jest\mockNativeComponent.js:17:18)
at children (node_modules\react-native-safe-area-context\lib\commonjs\SafeAreaContext.tsx:35:3)
at children (\node_modules\native-base\lib\commonjs\utils\createContext.tsx:9:13)
at colorModeManager (\node_modules\native-base\lib\commonjs\core\NativeBaseProvider.tsx:52:5)`
I'm using native-base version 3.4.19 and still have the issue! Any updates on this?
Yes, got the same error, please fix it 🙏
Update:
After updating to "native-base": "^3.4.25", jest no longer throws this error 👍
Hi The problem is still there but it has moved to a different file? Using 3.4.25
%s%s, TypeError: react_native_1.Dimensions.removeEventListener is not a function. (In 'react_native_1.Dimensions.removeEventListener('change', onChange)', 'react_native_1.Dimensions.removeEventListener' is undefined), in CheckinScreen (created by Screens)
node_modules/native-base/src/utils/useResponsiveQuery/common.ts
// The below implementation is taken from React Native's source and added a flag to conditionally attach/remove listeners
export const useDimensionsWithEnable = ({ enable }: { enable?: boolean }) => {
const [dimensions, setDimensions] = React.useState(() =>
Dimensions.get('window')
);
React.useEffect(() => {
if (enable) {
function handleChange({ window }: { window: ScaledSize }) {
if (
dimensions.width !== window.width ||
dimensions.height !== window.height ||
dimensions.scale !== window.scale ||
dimensions.fontScale !== window.fontScale
) {
setDimensions(window);
}
}
Dimensions.addEventListener('change', handleChange);
// We might have missed an update between calling `get` in render and
// `addEventListener` in this handler, so we set it here. If there was
// no change, React will filter out this update as a no-op.
handleChange({ window: Dimensions.get('window') });
return () => {
Dimensions.removeEventListener('change', handleChange); // <- HERE! ####################
};
}
return () => {};
}, [dimensions, enable]);
return dimensions;
};
Version 3.4.28
still has this bug:
console.error
Warning: Internal React error: Attempted to capture a commit phase error inside a detached tree. This indicates a bug in React. Likely causes include deleting the same fiber more than once, committ
ing an already-finished tree, or an inconsistent return pointer.
Error message:
TypeError: Cannot read properties of undefined (reading 'remove')
at HybridProvider (C:\personal_projects\clean-gta-clients\node_modules\native-base\lib\commonjs\core\hybrid-overlay\HybridProvider.tsx:9:3)
at ResponsiveQueryProvider (C:\personal_projects\clean-gta-clients\node_modules\native-base\lib\commonjs\utils\useResponsiveQuery\ResponsiveQueryProvider.tsx:20:12)
at RNCSafeAreaProvider
at Component (C:\personal_projects\clean-gta-clients\node_modules\react-native\jest\mockNativeComponent.js:17:18)
at SafeAreaProvider (C:\personal_projects\clean-gta-clients\node_modules\react-native-safe-area-context\src\SafeAreaContext.tsx:35:3)
at Provider (C:\personal_projects\clean-gta-clients\node_modules\native-base\lib\commonjs\utils\createContext.tsx:9:13)
at NativeBaseProvider (C:\personal_projects\clean-gta-clients\node_modules\native-base\lib\commonjs\core\NativeBaseProvider.tsx:52:5)
Same here but with the badge component, im doing the following:
const TestComponent = (props: Record<string, unknown>) => <View {...props} />
jest.mock('native-base', () => ({
...jest.requireActual('native-base'),
HamburgerIcon: () => <TestComponent testID="menu-icon" />,
AddIcon: () => <TestComponent testID="add-icon" />,
}))
the error:
TypeError: Cannot read properties of undefined (reading 'Badge')
7 | const TestComponent = (props: Record<string, unknown>) => <View {...props} />
8 |
> 9 | jest.mock('native-base', () => ({
| ^
10 | ...jest.requireActual('native-base'),
11 | HamburgerIcon: () => <TestComponent testID="menu-icon" />,
12 | AddIcon: () => <TestComponent testID="add-icon" />,
at Object.get [as Badge] (node_modules/native-base/lib/commonjs/index.js:95:24)
at Function.assign (<anonymous>)
at assign (app/test/ui/pages/HomePage/components/Header.test.tsx:9:26)
at Object.<anonymous> (node_modules/native-base/lib/commonjs/components/primitives/Hidden/HiddenSSR.tsx:2:1)
at Object.<anonymous> (node_modules/native-base/lib/commonjs/components/primitives/Hidden/index.tsx:9:1)
at Object.<anonymous> (node_modules/native-base/lib/commonjs/components/primitives/index.ts:69:1)
at Object.<anonymous> (node_modules/native-base/lib/commonjs/components/composites/Alert/AlertIcon.tsx:2:1)
at Object.<anonymous> (node_modules/native-base/lib/commonjs/components/composites/Alert/index.tsx:1:1)
at Object.<anonymous> (node_modules/native-base/lib/commonjs/components/composites/index.ts:13:1)
at Object.<anonymous> (node_modules/native-base/lib/commonjs/index.tsx:1:1)
Came across this and same issue as @joaosousafranco
jest.mock('native-base', () => {
console.log(jest.requireActual('native-base'))
return {
...jest.requireActual('native-base'),
Collapse: (props: ICollapseProps) => {
if (props.isOpen) {
props.onAnimationEnd?.()
}
return props.isOpen ? props.children : null
},
}
})
TypeError: Cannot read properties of undefined (reading 'Badge')
This solved the last two issues for me, from https://stackoverflow.com/a/70174052:
jest.requireActual inside of jest.mock seems like the way to go, however I needed to add a proxy instead of the object spread to prevent the type error Cannot read properties of undefined (reading ...) which can occur in certain import scenarios. This is the final result:
jest.mock('the-module-to-mock', () => {
const actualModule = jest.requireActual('the-module-to-mock')
return new Proxy(actualModule, {
get: (target, property) => {
switch (property) {
// add cases for exports you want to mock
// 👇👇👇
case 'foo': {
return jest.fn() // add `mockImplementation` etc
}
case 'bar': {
return jest.fn()
}
// fallback to the original module
default: {
return target[property]
}
}
},
})
})