ERROR Warning: Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.
Hi all, I'm updating some dependencies:
- react-native (0.61.5) to (0.63.2)
- react-navigation (^4.0.10) to (^4.4.0)
- react-native-screens ^2.11.0 (new add)
Package.json:
{ ... },"dependencies": {"@dudigital/react-native-zoomable-view": "^1.0.15","@react-native-community/async-storage": "^1.12.0","@react-native-firebase/app": "^7.1.0","@react-native-firebase/messaging": "^7.1.0","@sentry/react-native": "^1.7.2","amplitude-js": "5.5.0-react-native.1","axios": "^0.19.0","axios-extensions": "^3.0.6","date-fns": "^2.2.1","lodash": "^4.17.15","query-string": "^6.8.3","react": "16.9.0","react-native": "^0.63.2","react-native-android-dialog-picker": "^0.1.0","react-native-autogrow-textinput": "^5.3.0","react-native-background-fetch": "2.7.1","react-native-background-geolocation": "^3.4.2","react-native-background-timer": "^2.2.0","react-native-branch": "^4.3.0","react-native-camera": "^3.8.0","react-native-dash": "^0.0.11","react-native-device-info": "^5.6.5","react-native-elements": "^1.2.7","react-native-gesture-handler": "1.6.1","react-native-image-picker": "^2.2.0","react-native-keyboard-aware-scroll-view": "^0.9.1","react-native-linear-gradient": "^2.5.6","react-native-maps": "^0.25.0","react-native-material-textfield": "^0.12.0","react-native-pdf": "5.0.9","react-native-permissions": "^2.1.5","react-native-reanimated": "^1.3.0","react-native-screens": "^2.11.0","react-native-signature-capture": "^0.4.10","react-native-snap-carousel": "^3.8.4","react-native-splash-screen": "^3.2.0","react-native-svg": "^9.13.3","react-native-unimodules": "^0.7.0","react-native-vector-icons": "^6.6.0","react-native-walkme-sdk": "^2.0.12","react-native-webview": "9.4.0","react-navigation": "^4.4.0","react-navigation-hooks": "^1.1.0","react-navigation-stack": "^1.9.3","react-navigation-tabs": "^2.5.5","rn-fetch-blob": "^0.12.0","styled-components": "^4.3.2","tslint": "^5.18.0","ttag": "^1.7.18","yup": "^0.27.0" },"devDependencies": {"@babel/core": "^7.6.2","@babel/helper-validator-identifier": "^7.9.5","@babel/runtime": "^7.6.2","@types/amplitude-js": "^4.4.4","@types/jest": "^24.0.15","@types/lodash": "^4.14.138","@types/node": "^12.6.4","@types/react": "^16.8.22","@types/react-native": "^0.57.64","@types/react-native-dotenv": "^0.2.0","@types/react-native-elements": "^0.18.0","@types/react-native-material-textfield": "^0.12.3","@types/react-native-signature-capture": "^0.4.1","@types/react-native-snap-carousel": "^3.7.4","@types/react-navigation": "^3.0.8","@types/react-test-renderer": "^16.8.2","@types/styled-components": "^4.1.16","@types/yup": "^0.26.22","@typescript-eslint/eslint-plugin": "^1.13.0","@typescript-eslint/parser": "^1.13.0","babel-jest": "^24.9.0","dtslint": "^0.8.0","eslint": "^6.5.1","eslint-config-prettier": "^6.0.0","eslint-plugin-prettier": "^3.1.0","eslint-plugin-react": "^7.14.2","husky": "^1.3.1","jest": "^24.9.0","jetifier": "^1.6.4","lint-staged": "^8.1.4","metro-react-native-babel-preset": "^0.56.0","prettier": "^1.18.2","react-native-asset": "1.1.4","react-native-dotenv": "^0.2.0","react-test-renderer": "16.9.0","reactotron-react-native": "^4.0.2","tslint-config-prettier": "^1.18.0","tslint-react": "^4.0.0","tslint-react-hooks": "^2.2.1","ttag-cli": "^1.7.22","typescript": "3.5.2","typescript-styled-plugin": "^0.15.0" },"jest": {"preset": "react-native" }}
App.tsx:
import React, { useEffect, useState, useRef } from 'react';import { PermissionsAndroid, Platform, Alert } from 'react-native';import branch from 'react-native-branch';import { NavigationState, NavigationContainer } from 'react-navigation';import { ThemeProvider } from 'styled-components';import SplashScreen from 'react-native-splash-screen';import amplitude from 'amplitude-js';import AmplitudeClient from 'amplitude-js';import DeviceInfo from 'react-native-device-info';import { useLocale } from 'ttag';import messaging from '@react-native-firebase/messaging';import getAppNavigator from './navigation/AppNavigator';import config from './config';import theme from './theme';import { getItem, setItem } from './utils/storage';import { getActiveRouteName, getActiveRouteParams } from './navigation/utils';import { fetchToken, AccessToken, FetchTokenParams } from './services/auth';import { areParamsForOnboarding } from './services/branch';import { usePublicFetch } from './hooks/fetching';import { LocaleProvider, Locale, updateLocale, getLocaleFromStorage } from './locale';const App = () => { const [AppNavigator, setAppNavigator] = useState<NavigationContainer>(); const branchParams = useRef<branch.Params>(); const [query, fetchTokenParams] = usePublicFetch<AccessToken, FetchTokenParams>(fetchToken); const [realizarQuery, setRealizarQuery] = useState(true); function finishLoading(accessToken?: string, refreshToken?: string) { if (accessToken && refreshToken) { config.accessToken = accessToken; config.refreshToken = refreshToken; } setAppNavigator(() => { if (branchParams.current && areParamsForOnboarding(branchParams.current)) { return getAppNavigator(!!accessToken, { companyId: branchParams.current.companyId, newCompany: branchParams.current.newCompany, travelOrderId: branchParams.current.travelOrderId, }); } return getAppNavigator(!!accessToken); }); SplashScreen.hide(); } useEffect(() => { (async () => { const accessToken = await getItem('accessToken'); const refreshToken = await getItem('refreshToken'); const p = await branch.getLatestReferringParams(); if (accessToken && refreshToken) { finishLoading(accessToken, refreshToken); } else if (areParamsForOnboarding(p)) { branchParams.current = p; fetchTokenParams({ user: p.username, pass: p.authorizationcode, }); } else { finishLoading(); } })(); }, []); useEffect(() => { if (query.data && realizarQuery) { setRealizarQuery(false); finishLoading(query.data.access_token, query.data.refresh_token); savingToken(query.data.access_token, query.data.refresh_token); } }, [query]); if (!AppNavigator) { return null; } return (<AppNavigator onNavigationStateChange={(prevState: NavigationState, currentState: NavigationState) => { const currentScreen = getActiveRouteName(currentState); const prevScreen = getActiveRouteName(prevState); const params = getActiveRouteParams(currentState); if (prevScreen !== currentScreen) { // We also update amplitude every single time a navigation occurs amplitude.getInstance().logEvent(`${currentScreen.toLowerCase()}.viewed`, params); } }} /> );};export default () => { const [locale, setLocale] = useState<Locale>('en'); useEffect(() => { getLocaleFromStorage().then(storedLocale => { useLocale(storedLocale); // ttag change of locale setLocale(storedLocale); }); }, []); return (<ThemeProvider theme={theme}><LocaleProvider value={{ locale, setLocale: (locale: Locale) => { updateLocale(locale); // ttag & async storage change of locale setLocale(locale); }, }}><App /></LocaleProvider></ThemeProvider> );};
In App.tsx the problem is that I get an issue related with the function, getAppNavigator(!!accessToken):NavigationContainer this is because is a function and it's expecting an JSX.element like this:
AppNavigator:NavigationContainer
Q: It's possible to keep using a function as a NavigationContainer ?
Screenshot of the issue
Thank you so much!