React Native: Invalid hook call - react-native

I am trying to make android application with react native.After creating project and install all dependencies i want to use use Hook inside navigator like this:
const MainNavigator = createStackNavigator({
Dashboard: DashboardScreen,
ListSurveyor: {
screen: topSurvayorsNavigator,
navigationOptions: ({ navigation }) => {
const dispatch = useDispatch();
const [term, setTerm] = useState('');
const searchServeyor = (item) => {
console.log('nav: ', item);
dispatch(survayouActions.searchSurveyouList(item))
}
switch (navigation.state.routes[navigation.state.index]["routeName"]) {
case "ActiveSurveyor":
return {
header: () => <CustomHeader
title='Active'
// term={term}
// onTermChange={setTerm}
onTermSubmit={searchServeyor}
/>
}
case "DeActiveSurveyor":
return {
header: () => <CustomHeader
title='DisActive'
onTermSubmit={searchServeyor}
/>
}
default:
return { title: (navigation.state.routes[navigation.state.index]["routes"])[(navigation.state.routes[navigation.state.index]["index"])].routeName }
}
}
},
Audited: AuditedFileNumSurveyor,
}, {
defaultNavigationOptions: defaultNavOptions
});
I imported useState and useDispatch like below:
import React, { useState } from 'react';
import { useDispatch } from "react-redux";
But When i run application i got this error:
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app See for tips about how to debug and fix this problem.
I used hook inside method navigationOptions: ({ navigation }) => { but what is happen?
This is package.json information:
{
"name": "RNMngm",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"base-64": "^0.1.0",
"prop-types": "^15.7.2",
"react": "16.9.0",
"react-native": "0.61.5",
"react-native-charts-wrapper": "^0.5.7",
"react-native-gesture-handler": "^1.5.2",
"react-native-paper": "^3.4.0",
"react-native-reanimated": "^1.4.0",
"react-native-svg": "^10.0.0",
"react-native-vector-icons": "^6.6.0",
"react-navigation": "^4.0.10",
"react-navigation-drawer": "^2.3.3",
"react-navigation-header-buttons": "^3.0.4",
"react-navigation-material-bottom-tabs": "^2.1.5",
"react-navigation-stack": "^1.10.3",
"react-navigation-tabs": "^2.7.0",
"react-redux": "^7.1.3",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0"
},
"devDependencies": {
"#babel/core": "7.7.7",
"#babel/runtime": "7.7.7",
"#react-native-community/eslint-config": "0.0.5",
"babel-jest": "24.9.0",
"eslint": "6.8.0",
"jest": "24.9.0",
"metro-react-native-babel-preset": "0.56.3",
"react-test-renderer": "16.9.0"
},
"jest": {
"preset": "react-native"
}
}

Hooks can only be used in a component, and cannot be used in navigator or navigationOptions. If u need to use state in navigator or navigationOptions, u need to setParams in the component and then use the getParam method in navigationOptions

Related

react navigation issue with versions

I have a problem when I try to add a bottomnavigation in my app on the main screen:
This is the main screen code:
// Main.js
import React from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
import firebase from 'react-native-firebase';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
export default class Main extends React.Component {
state = { currentUser: null }
componentDidMount() {
const { currentUser } = firebase.auth()
this.setState({ currentUser })
}
render() {
const { currentUser } = this.state
return (
<View style={styles.container}>
<Text>
Hi {currentUser && currentUser.email}!
</Text>
</View>
)
}
}
const bottomTabNavigator = createBottomTabNavigator(
{
Main: Main,
},
{
initialRouteName: 'Main'
}
);
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
})
No when I run it I get this error:
Error: Creating a navigator doesn't take an argument. Maybe you are trying to use React Navigation 4 API with React Navigation 5? See https://reactnavigation.org/docs/en/hello-react-navigation.html for usage guide.
<unknown>
index.bundle?platform=ios&dev=true&minify=false:109707:24
<global>
Main.js:24
loadModuleImplementation
require.js:322:6
guardedLoadModule
require.js:201:45
runUpdatedModule
require.js:657:17
metroHotUpdateModule
require.js:533:8
define
require.js:53:24
global code
Main.bundle?platform=ios&dev=true&minify=false&modulesOnly=true&runModule=false&shallow=true:1:4
<unknown>
[native code]:0
inject
injectUpdate.js:62:35
forEach
[native code]:0
injectUpdate
injectUpdate.js:71:26
on$argument_1
HMRClient.js:40:21
emit
index.js:202:37
_ws.onmessage
WebSocketHMRClient.js:72:20
EventTarget.prototype.dispatchEvent
event-target-shim.js:818:39
_eventEmitter.addListener$argument_1
WebSocket.js:232:27
emit
EventEmitter.js:190:12
callFunctionReturnFlushedQueue
[native code]:0
So i checked my package file which is:
{
"name": "kowop",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"#react-native-community/masked-view": "^0.1.6",
"#react-navigation/bottom-tabs": "^5.0.3",
"#react-navigation/material-bottom-tabs": "^5.0.1",
"#react-navigation/native": "^5.0.1",
"email-validator": "^2.0.4",
"react": "16.9.0",
"react-native": "0.61.5",
"react-native-firebase": "^5.6.0",
"react-native-gesture-handler": "^1.5.6",
"react-native-paper": "^3.6.0",
"react-native-reanimated": "^1.7.0",
"react-native-safe-area-context": "^0.6.4",
"react-native-screens": "^2.0.0-beta.2",
"react-native-vector-icons": "^6.6.0",
"react-navigation": "^4.1.1",
"react-navigation-stack": "^2.0.16",
"typescript": "^3.7.5"
},
"devDependencies": {
"#babel/core": "7.8.3",
"#babel/runtime": "7.8.3",
"#react-native-community/eslint-config": "0.0.5",
"babel-jest": "24.9.0",
"eslint": "^6.8.0",
"jest": "24.9.0",
"metro-react-native-babel-preset": "0.56.4",
"react-test-renderer": "16.9.0"
},
"jest": {
"preset": "react-native"
}
}
But apparently react-navigation can't be updated above 4.11 or at least that is what the npm page says.
244,663
Version
4.1.1
License
MIT
Unpacked Size
41 kB
Total Files
12
Issues
133
Pull Requests
3
So I am a bit lost here. Does anyone see what I do wrong?
Thanks a lot!
Tim
You are using react-navigation v5 dependencies but in your code you implement with v4 api way.
You should change react-navigation dependencies to v4 to make your code work.
I made you code work on snack : demo

Get icons to work with Vue native / React Native - createMaterialBottomTabNavigator

I'm trying to get the bottom tab navigator to show the icons for Vue Native.
I'm new to coding, and it's a little bit confusing for me to understand some bits how Vue native and React native syntax works. I searched the internet hi and low to find the information that I needed.
I did find some information on the official React Native website.
The Vue native official website doesn't contain so much detailed information regarding this.
So, my question is how do I get this to work? The code below spits out an error code when I try to execute it.
Thanks in advance for the help :)
// Chris
I leave some code snippets below:
<template>
<app-navigator></app-navigator>
</template>
<script>
import {
createAppContainer,
createMaterialBottomTabNavigator,
createStackNavigator,
} from "vue-native-router";
import Icon from '../node_modules/react-native-vector-icons/dist/FontAwesome.js';
import Home from "./screens/HomeScreen.vue";
import Message from "./screens/Message.vue"
const StackNavigator = createMaterialBottomTabNavigator({
Hem: Home,
Message: {
screen: Message,
navigationOptions: {
title: 'woop',
tabBarIcon: ({tintColor})=>{
<Icon name="ios-home" color={tintColor} size={25}/>
}
},
},
});
const AppNavigator = createAppContainer(StackNavigator);
export default {
components: { Root, AppNavigator },
}
</script>
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject"
},
"dependencies": {
"axios": "^0.19.0",
"expo": "~36.0.2",
"expo-font": "~8.0.0",
"native-base": "^2.13.8",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-36.0.0.tar.gz",
"react-native-gesture-handler": "^1.5.2",
"react-native-paper": "^3.4.0",
"react-native-reanimated": "^1.4.0",
"react-native-vector-icons": "^6.6.0",
"react-native-web": "~0.11.7",
"react-navigation-material-bottom-tabs": "^2.1.5",
"vue-axios": "^2.1.5",
"vue-native-core": "^0.1.4",
"vue-native-helper": "^0.1.4",
"vue-native-router": "^0.1.1"
},
"devDependencies": {
"#babel/core": "^7.7.7",
"babel-preset-expo": "~8.0.0",
"vue-native-scripts": "^0.1.4"
},
"private": true
}
I got it working by adding this:
import * as React from 'react';
import Icon from 'react-native-vector-icons/FontAwesome';
Message: {
screen: Message,
navigationOptions: {
tabBarLabel: 'Meddelanden',
tabBarIcon: <Icon name="rocket" size={25}/>,
}
}

When I Press Back Button(from the stack header) or swipe left to right, ios app crashes

When I Press Back Button(In the stack header) or swipe left to right in a physical iPhone device my react native app crashes. The App is working fine in the simulator but not in a physical device.
So, how can I fix this issue?
Here is the code for my main navigator
import { themeColor, themeColorLite } from "../styles/common";
import Login from "../views/Login"
import ForgetPass from "../views/forgetPass"
import Registration from "../views/Registration"
import UserDashboard from "../views/user/dashboard"
import ProductDetails from "../views/user/productDetails"
import ShoppingMall from "../views/user/shoppingMalls"
import Shops from "../views/user/shops"
import NormalProducts from "../views/user/normalProducts"
import ShoppingCart from "../views/user/shoppingCart"
import UserProfile from "../views/user/profile"
import { createSwitchNavigator, createAppContainer } from 'react-navigation'
import { createStackNavigator } from 'react-navigation-stack'
import { createDrawerNavigator } from 'react-navigation-drawer'
import UserDrawerNav from '../views/drawerNav'
const ProductStackNavigator = createStackNavigator({
UserDashboard: UserDashboard,
ProductDetails: ProductDetails,
ShoppingCart: ShoppingCart,
ShoppingMall: ShoppingMall,
Shops: Shops,
NormalProducts: NormalProducts
})
const DrawerNavigator = createDrawerNavigator(
{
UserDashboard: ProductStackNavigator,
ShoppingMall: ProductStackNavigator,
UserProfile: UserProfile
},
{
contentComponent: UserDrawerNav,
hideStatusBar: true,
drawerBackgroundColor: 'white',
overlayColor: themeColorLite,
contentOptions: {
activeTintColor: '#fff',
activeBackgroundColor: themeColor,
}
}, {
unmountInactiveRoutes: true
}
);
const AuthStack = createSwitchNavigator({
Login: { screen: Login } ,
Registration: { screen: Registration } ,
ForgetPass: { screen: ForgetPass }
});
const AppContainer = createAppContainer(createSwitchNavigator(
{
App: DrawerNavigator,
Auth: AuthStack
},
{
initialRouteName: 'Auth',
}
));
export default AppContainer;
Here is my package.json
{
"name": "ENC",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"ipadAir": "react-native run-ios --simulator 'iPad Air (3rd generation)'",
"start": "react-native start",
"iphone11": "react-native run-ios --simulator 'iPhone 11'",
"cleanStart": "react-native start --reset-cache",
"link": "react-native link",
"podInstall": "cd ios && pod install && cd ..",
"podUpdate": "cd ios && pod update && cd ..",
"upgradeRN": "react-native upgrade",
"regenDir": "react-native upgrade --legacy true",
"test": "jest"
},
"dependencies": {
"#react-native-community/async-storage": "^1.6.1",
"axios": "^0.19.0",
"react": "16.10.1",
"react-native": "0.61.2",
"react-native-flip-card": "^3.5.5",
"react-native-fs": "^2.14.1",
"react-native-gesture-handler": "^1.4.1",
"react-native-image-picker": "^1.1.0",
"react-native-photo-upload": "^1.3.0",
"react-native-really-awesome-button": "^1.4.2",
"react-native-reanimated": "^1.2.0",
"react-native-tiny-toast": "^1.0.3",
"react-native-webview": "^7.4.0",
"react-native-xml2js": "^1.0.3",
"react-navigation": "^4.0.5",
"react-navigation-drawer": "^2.2.1",
"react-navigation-stack": "1.5.1"
},
"devDependencies": {
"#babel/core": "^7.5.0",
"#babel/runtime": "^7.5.0",
"#react-native-community/eslint-config": "^0.0.5",
"babel-jest": "^24.1.0",
"jest": "^24.1.0",
"metro-react-native-babel-preset": "^0.56.0",
"react-test-renderer": "16.10.1"
},
"jest": {
"preset": "react-native"
}
}
The above code is also available at my gist here
Finally found the solution after profiling the issue in xcode
this solution is work for me fine :
https://github.com/kmagiera/react-native-gesture-handler/issues/320#issuecomment-447534290

Jest Encountered Unexpected token with import statement

I've tried many fixes based on SO and GH answers but none have worked.
I'm trying to set up Jest and Enzyme for my React Native project but I can't get tests to run. Here's my current test file:
import React from "react";
import { shallow, mount } from "enzyme";
// import MapScreen from "../src/screens/MapView";
describe("MapScreen", () => {
it("should render tab bar icons", () => {
expect(true).toEqual(true); // just to get tests working at all!
});
});
The error:
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
/Users/TuzMacbookPro2017/Development/QMG-local/APPS/ELECTRO/node_modules/expo/build/environment/validate.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import {
^
SyntaxError: Unexpected token {
at ScriptTransformer._transformAndBuildScript (node_modules/#jest/transform/build/ScriptTransformer.js:471:17)
at ScriptTransformer.transform (node_modules/#jest/transform/build/ScriptTransformer.js:513:25)
at Object.<anonymous> (node_modules/expo/build/Expo.js:278:1)
My config files:
// jest.config.js
module.exports = {
setupFilesAfterEnv: ["<rootDir>setup-tests.js"],
transformIgnorePatterns: [
"node_modules/(?!(jest-)?react-native|#react-native-community|react-native-elements)"
]
};
// babel.config.js
module.exports = function(api) {
api.cache(true);
return {
presets: ["babel-preset-expo"]
};
};
// setup-tests.js
import Adapter from "enzyme-adapter-react-16";
import { configure } from "enzyme";
import jsdom from "jsdom";
import "react-native";
import "jest-enzyme";
function setUpDomEnvironment() {
const { JSDOM } = jsdom;
const dom = new JSDOM("<!doctype html><html><body></body></html>", {
url: "http://localhost/"
});
const { window } = dom;
global.window = window;
global.document = window.document;
global.navigator = {
userAgent: "node.js"
};
copyProps(window, global);
}
function copyProps(src, target) {
const props = Object.getOwnPropertyNames(src)
.filter(prop => typeof target[prop] === "undefined")
.map(prop => Object.getOwnPropertyDescriptor(src, prop));
Object.defineProperties(target, props);
}
setUpDomEnvironment();
configure({ adapter: new Adapter() });
// package.json
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"eject": "expo eject",
"test": "node ./node_modules/jest/bin/jest.js --watchAll"
},
"jest": {
"preset": "jest-expo",
"testEnvironment": "node",
"globals": {
"__DEV__": true
}
},
"dependencies": {
"#expo/samples": "2.1.1",
"#react-native-community/async-storage": "^1.3.4",
"expo": "^32.0.0",
"native-base": "^2.12.1",
"react": "16.5.0",
"react-dom": "^16.8.6",
"react-native": "0.57",
"react-native-elements": "^1.1.0",
"react-native-geocoding": "^0.3.0",
"react-native-global-font": "^1.0.2",
"react-native-indicators": "^0.13.0",
"react-native-keyboard-aware-scrollview": "^2.0.0",
"react-native-material-dropdown": "^0.11.1",
"react-native-render-html": "^4.1.2",
"react-native-uuid": "^1.4.9",
"react-navigation": "^3.9.1",
"react-redux": "^6.0.1",
"redux": "^4.0.1",
"redux-test-utils": "^0.3.0",
"redux-thunk": "^2.3.0",
"sugar": "^2.0.6"
},
"devDependencies": {
"#babel/preset-react": "^7.0.0",
"babel-preset-expo": "^5.0.0",
"babel-preset-react-native": "^4.0.1",
"enzyme": "^3.9.0",
"enzyme-adapter-react-16": "^1.12.1",
"fetch-mock": "^7.3.3",
"jest": "^24.8.0",
"jest-enzyme": "^7.0.2",
"jest-expo": "^32.0.0",
"jsdom": "^14.1.0",
"mock-async-storage": "^2.1.0",
"react-test-renderer": "^16.8.6",
"redux-mock-store": "^1.5.3"
},
"private": true,
"rnpm": {
"assets": [
"./assets/fonts"
]
}
}
I can't get even this simple test to run. I have actually been able to get that test to run on a different branch, and copied all the test-related config files from that branch to this one, but I'm still getting this error.
I know there are many posts about this around but none seem to help me. I hope someone can help me get this working! Thanks!

Jest: How to fix - TypeError: Cannot assign to read only property 'name' of function 'function ()

Im using react-native-paper within my own functional component.
I want to write Jest tests for my component.
Problem:
When I import my component to the Jest test file I receive this error:
TypeError: Cannot assign to read only property 'name' of function 'function () {for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {ar...<omitted>... }'
at node_modules/react-native-paper/src/core/withTheme.js:136:46
at Array.forEach (<anonymous>)
at withTheme (node_modules/react-native-paper/src/core/withTheme.js:124:5)
at Object.<anonymous> (node_modules/react-native-paper/src/components/Typography/Text.js:46:24)
at Object.<anonymous> (node_modules/react-native-paper/src/components/BottomNavigation.js:16:48)`
Trying to narrow the error I found out that even this simple Jest file will cause the error.
Reproducer
import React from 'react';
import { Provider as PaperProvider } from 'react-native-paper';
describe('Unit Tests - Component:', () => {
it('s a test', () => {});
});
My package.json:
{
"name": "TodoList",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"prettier": "prettier --write '*.js'",
"format-code": "yarn run prettier && yarn run lint:fix",
"precommit": "lint-staged",
"test:coverage": "jest --coverage && open coverage/lcov-report/index.html"
},
"lint-staged": {
"*.js": ["yarn run format-code", "git add"]
},
"dependencies": {
"firebase": "^5.5.3",
"prop-types": "^15.6.0",
"react": "16.4.1",
"react-native": "0.56.0",
"react-native-image-picker": "^0.26.7",
"react-native-keychain": "^3.0.0",
"react-native-paper": "^1.0.1",
"react-native-vector-icons": "^5.0.0",
"react-navigation": "^1.5.12",
"react-redux": "^5.0.7",
"redux": "^3.7.2",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
"yarn": "^1.9.4"
},
"devDependencies": {
"babel-eslint": "^8.2.2",
"babel-jest": "22.4.1",
"babel-preset-react-native": "^5.0.2",
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.6.0",
"eslint": "^4.18.1",
"eslint-config-airbnb": "^16.1.0",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.7.0",
"husky": "^0.14.3",
"jest": "22.4.2",
"jest-fetch-mock": "^2.1.0",
"lint-staged": "^7.2.2",
"prettier": "1.10.2",
"react-dom": "^16.7.0",
"react-test-renderer": "16.4.1",
"redux-mock-store": "^1.5.3"
},
"jest": {
"preset": "react-native",
"setupFiles": ["<rootDir>/tests/setup.js"],
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
},
"collectCoverageFrom": ["app/**/*.js", "!app/components/index.js"]
}
}
I faced the same issue for window.location.reload:
TypeError: Cannot assign to read only property 'reload' of object '[object Location]'
I did the following to make it work:
const reload = window.location.reload;
beforeAll(() => {
Object.defineProperty(window, 'location', {
value: { reload: jest.fn() }
});
});
afterAll(() => {
window.location.reload = reload;
});
it('my test case', () => {
// code to test the call to reload
expect(window.location.reload).toHaveBeenCalled();
});
Jest version: 26.6.3
react-scripts version: 4.0.1
Note
The issue appeared after upgrading to react-scripts version 4.0.1.
Solution:
import { DefaultTheme, Provider as PaperProvider } from 'react-native-paper';
describe('Unit Test', () => {
const theme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
},
};
const props = {};
beforeEach(() => {
renderedComponent = renderer
.create(<PaperProvider theme={theme}>
<MyCompoment {...props} />
</PaperProvider>)
.toJSON();
// basic tests
it(`${componentName} renders successfully`, () => {
expect(renderedComponent).toBeTruthy();
});
}