Application not loaded after upgrade from React-navigation 4 to React-Navigation 6 - react-native

after upgrade from React-navigation 4 to React-navigation 6 the default imports cause undefined errors when used for assignments.
The Application uses expo, Expo SDK version is 44.
This error occurs when opening the application
Application error
RoutesNavigators.js
import * as React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import ConfigsLoading from './screens/commons/configs_loading';
const Stack = createNativeStackNavigator();
const RoutesNavigator = () => (
<NavigationContainer>
<Stack.Navigator initialRouteName="ConfigsLoading" screenOptions={{ headerShown: false }}>
<Stack.Screen name="ConfigsLoading" component={ConfigsLoading} />
</Stack.Navigator>
</NavigationContainer>
);
export default RoutesNavigator;
configs_loading / index.jsx
/* eslint-disable no-constant-condition */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { View, ActivityIndicator, Text } from 'react-native';
import { connect } from 'react-redux';
import { translate } from 'react-i18next';
import lojas from '../../features/lojas';
import { styles } from './styles';
import pushTokens from '../../../infra/push_tokens';
import usuarios from '../../features/usuario';
import campanhas from '../../features/campanhas';
class ConfigsLoading extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<View style={styles.container}>
<ActivityIndicator size="large" color="#999999" />
<Text>{this.props.t('commons:carregando')}</Text>
</View>
);
}
}
ConfigsLoading.propTypes = {
navigation: PropTypes.object.isRequired,
credenciais: PropTypes.object.isRequired,
recuperarLojaFavorita: PropTypes.func.isRequired,
setarLojaCorrente: PropTypes.func.isRequired,
recuperarCredencial: PropTypes.func.isRequired,
aceitarTermosUso: PropTypes.func.isRequired,
t: PropTypes.func.isRequired,
criarTokenUsuario: PropTypes.func.isRequired,
pushToken: PropTypes.string,
recuperarCampanhaVigente: PropTypes.func.isRequired,
};
ConfigsLoading.defaultProps = {
pushToken: undefined,
};
const mapStateToProps = state => ({
salvandoLojaFavorita: lojas.selectors.obterSalvandoLojaFavorita(state),
pushToken: pushTokens.selectors.obterToken(state),
credenciais: usuarios.selectors.obterCredencial(state),
aceitandoTermosUso: usuarios.selectors.obterAceitandoTermosUso(state),
excluidoCredencialUsuario: usuarios.selectors.obterExcluindoCredencial(state),
});
const obj = translate(['common'], { wait: true })(ConfigsLoading);
export default connect(mapStateToProps, {
...lojas.actions, ...pushTokens.actions, ...usuarios.actions, ...campanhas.actions,
})(obj);
lojas / index.js
import Container from './components/Container';
import Lista from './components/Lista';
import * as constants from './constants';
import * as actions from './actions';
import * as selectors from './selectors';
import reducer from './reducer';
export default {
Container,
Lista,
reducer,
constants,
actions,
selectors,
};
pushTokens, campanhas and usuarios files has te same export as the lojas file
i have the following plugins in my babel.config.js
"babel-plugin-module-resolver",
"react-native-reanimated/plugin"

Related

How Do you access function props in your class component?

I am trying to set up react redux, also i have set it but I am getting an error TypeError: _this.props.showLoader is not a function. (In '_this.props.showLoader(true)', '_this.props.showLoader' is undefined).
this.props.showLoader(true)
This function has been defined in Action.js file you can find it below.
This error comes whenever I try to call a function from Root.js file, you can find it below.
Below is the code what I have done so far:->
I have App.js file in which I have set for provider and store
import React, { Component } from 'react';
import {StyleSheet, View, Text} from 'react-native';
import {Provider} from 'react-redux';
import store from './src/redux/Store'
import Root from './src/root/Root'
function App() {
return (
<Provider store={store}>
<View style={localStyles.container}>
<Root/>
</View>
</Provider>
);
}
export default App;
const localStyles = StyleSheet.create({
container: {
flex: 1,
},
});
This is the Navigation Route File
import React from 'react'
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import TutorialSwipeScreen from '../components/viewcontrollers/onboarding/TutorialSwipeScreen'
const Stack = createStackNavigator();
function goStack() {
return (
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerShown: false
}}
>
<Stack.Screen name="Login" component={Login Screen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default goStack;
My Root.js file
where I am trying to this.props.showLoader it gives me error
import React, {Component} from 'react'
import {View, StyleSheet, Text} from 'react-native'
import NavigationRoute from './NavigationRoutes'
import DeviceInfo from 'react-native-device-info'
class Root extends Component {
constructor(props) {
super(props)
console.warn('props=', this.props)
}
componentDidMount() {
this.call()
}
call = () => {
this.props.showLoader(true)
}
render () {
return (
<View style={styles.rootContainer}>
<NavigationRoute/>
</View>
)
}
}
export default Root;
const styles = StyleSheet.create({
rootContainer: {
flex: 1,
}
});
My RootContainer.js File
import {bindActionCreators} from 'redux'
import {connect} from 'react-redux'
import * as Actions from '../redux/Actions'
import Root from './Root'
function mapStateToProps(state) {
return {
shouldShowLoader: state.dataReducer._showLoader,
shouldChangeCounting: state.dataReducer.counter
}
}
function mapDispatchToProps(dispatch) {
const mergedActions = Object.assign({}, Actions);
return bindActionCreators(mergedActions, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps)(Root);
My Store.js file
import {createStore} from 'redux'
import reducers from './RootReducer'
export default createStore(reducers);
My RootReducer.js
import {combineReducers} from 'redux'
import dataReducer from './reducers/Reducer'
const rootReducer = combineReducers ({
dataReducer,
})
export default rootReducer;
My Action.js file which has a function showLoader(bool) which I try to call from Root.js which gives me an error as I have quoted above.
export const DISPLAY_LOADER = 'DISPLAY_LOADER';
export const REFRESH = 'REFRESH';
export const COUNTER = 'COUNTER';
export function showLoader(bool) {
return {
type: DISPLAY_LOADER, data: bool,
};
}
export function refresh() {
return {
type: REFRESH, data: true,
};
}
export function counting(count) {
return {
type: COUNTER, data: count
}
}
And Finally Reducer.js file code goes here
import { DISPLAY_LOADER, REFRESH, WELCOME_POPUP, LOGIN_RELOAD, MESSAGE_POPUP, LOGOUT, COUNTER} from '../Actions';
const initialState = {
counter: 5,
_showLoader: false,
_showMessagePopup: false,
_loginReload: false,
_refresh: false,
_heading: 'Message Heading',
_message: 'PWG Custom Message',
}
const dataReducer = (state = initialState, action) => {
switch(action.type) {
case DISPLAY_LOADER: {
return {...initialState, _showLoader: action.data}
}
case REFRESH: {
return {...initialState, _refresh: action.data}
}
case LOGOUT: {
return {...initialState, _refresh: true}
}
case COUNTER: {
return {...initialState, counter: action.data}
}
default: {
return state;
}
}
}
export default dataReducer;
So where my mistake is I am not able to find with what lines of code I am receiving error at my end. Please help. Also I am new to react native please bear with me.
Thanks
I have got the answer, I am answering my own post.
In the App.js File You need to import
RootContainer
instead of
Root
That’s it and it works Voila.
import RootContainer from './src/root/RootContainer'
I see that your showLoader tied to your redux reducer.
what i can suggest you, you should return state not initialState in your reducer. Basically what youre doing is after each change of state in redux, everything else will go back to its initialState but not the changed state itself.
You also didn't pass props showLoader to your Root component. If your intention is using showLoader as a setState function for your Root component, you should define the function in your mapDispatchToProps in your connect function

React Navigation update screen on specific tab

I'm new on react native. I have navigation (bottom navigation) with Setting screen and TopNavigation.
Inside TopNavigation I have dynamic tab with 1 screen (multiple tab with 1 screen). The problem is, MainComponent.js would receive the results at componentWillReceiveProps() and how to send or update data from nextProps to my specific dynamic tab? Or maybe my code in the wrong way?
You can see my image, my multiple tab with 1 screen, and have 1 button to fetch data. And this is my code:
index.js
import React from 'react';
import {AppRegistry} from 'react-native';
import {name as appName} from './app.json';
//Redux
import {applyMiddleware, createStore} from 'redux';
import {Provider} from 'react-redux';
//reducers
import allReducers from './App/reducers';
import MainContainer from './App/Containers/MainContainer';
//Redux saga
import createSagaMiddleware from 'redux-saga';
import rootSaga from './App/sagas/rootSaga';
const sagaMiddleware = createSagaMiddleware();
let store = createStore(allReducers, applyMiddleware(sagaMiddleware));
const Main = () => (
<Provider store={store}>
<MainContainer />
</Provider>
);
sagaMiddleware.run(rootSaga);
AppRegistry.registerComponent(appName, () => Main);
MainContainer.js
import {connect} from 'react-redux';
import MainComponent from '../Components/MainComponent';
import {fetchCategoriesAction} from '../actions/categoriesAction';
import {fetchTestAction} from "../actions/testAction";
const mapStateToProps = (state) => {
return {
receivedCategories: state.categoriesReducer,
receivedMovies: state.testingReducer,
navigation: state.navigation
}
};
const mapDispatchToProps = (dispatch) => {
return {
onFetchCategories: (payload) => {
console.log("mapDispatchToProps");
dispatch(fetchCategoriesAction(payload));
},
onFetchTest: (payload) => {
dispatch(fetchTestAction(payload))
}
};
};
const MainContainer = connect(mapStateToProps, mapDispatchToProps)(MainComponent);
export default MainContainer;
MainComponent.js
import React, {Component} from "react";
import {createAppContainer, createMaterialTopTabNavigator} from 'react-navigation'
import {createMaterialBottomTabNavigator} from "react-navigation-material-bottom-tabs";
import {tabBarOptions} from "../Navigation/Top/Options";
import Test from "./Screens/Test";
import Setting from "./Screens/Setting";
export default class MainComponent extends Component {
constructor(props) {
super(props);
this.state = {myNavigator: null, movies: [], categories: []}
}
componentWillMount() {
this.props.onFetchCategories({p1: 1});
}
createNavigator(categories) {
if (categories != null) {
const screens = {};
categories.forEach(page => {
screens[page.slug] = {
screen: Test,
};
});
let TopNavigator = createMaterialTopTabNavigator(screens, {
tabBarOptions,
lazy: true,
});
const AppNavigator = createMaterialBottomTabNavigator({
B1: TopNavigator,
B2: Setting,
});
const AppContainer = createAppContainer(AppNavigator);
this.setState({myNavigator: <AppContainer screenProps={this.props}/>});
}
}
componentWillReceiveProps(nextProps) {
console.log(nextProps);
if (nextProps.receivedCategories !== null && nextProps.receivedCategories.categories !== this.state.categories) {
this.setState({categories: nextProps.receivedCategories.categories});
this.createNavigator(nextProps.receivedCategories.categories)
}
}
render() {
return this.state.myNavigator;
}
}
Test.js
import React, {Component} from "react";
import {Text, Container, Button} from 'native-base'
export default class Test extends Component {
constructor(props) {
super(props);
}
render() {
return (
<Container>
<Button onPress={ () => {
this.props.screenProps.onFetchTest({slug: this.props.navigation.state.routeName})
}}><Text>Fetch Data</Text></Button>
<Text>Test screen {this.props.navigation.state.routeName}</Text>
<Text>I want this part changed when i click fetch data button</Text>
</Container>
)
}
}
Thank you!

createReduxBoundAddListener is deprecated in react-navigation-redux-helpers#2.0.0! Please use reduxifyNavigator instead

I'm using react-navigation and redux for navigation between screens I'm getting an error instead.
Invariant Violation: createReduxBoundAddListener is deprecated in
react-navigation-redux-helpers#2.0.0! Please use reduxifyNavigator
I don't know how to fix it please help me out.
App.js
import React from 'react';
import { Provider } from "react-redux";
import store from "./src/redux/store"
import { createReduxBoundAddListener } from "react- navigation-redux-helpers";
import AppWithNavigationState from "./src/navigators/AppNavigator";
export default class App extends React.Component {
render() {
return (
<Provider store={store}>
//Here Im getting an error regarding creacteReduxBoundAddListener
<AppWithNavigationState listener{createReduxBoundAddListener("root")}/>
</Provider>
);
}
}
AppNavigator.js file
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import {connect} from "react-redux";
import {PropTypes} from 'prop-types';
import {addNavigationHelpers,createStackNavigator } from "react-navigation";
import LoggedOut from "../screens/LoggedOut";
import LogIn from "../screens/Login";
import ForgotPassword from "../screens/ForgotPassword";
// created screens using createStackNavigator
export const AppNavigator = createStackNavigator({
LoggedOut:{screen:LoggedOut},
LogIn:{screen:LogIn},
ForgotPassword:{screen:ForgotPassword},
});
const AppWithNavigationState = ({ dispatch,nav,listener}) =>{
<AppNavigator navigation=
{addNavigationHelpers({dispatch,state:nav,addListener:listener})}/>
};
AppWithNavigationState.propTypes = {
dispatch:PropTypes.func.isRequired,
nav:PropTypes.object.isRequired
};
const mapStateToProps = state =>({
nav:state.nav,
});
export default connect(mapStateToProps)(AppWithNavigationState);
navigation.js
import {AppNavigator} from "../../navigators/AppNavigator";
const firstAction =
AppNavigator.router.getActionForPathAndParams("LoggedOut"); //decide which
//screen will
//load first
const initialNavState = AppNavigator.router.getStateForAction(firstAction);
export const nav = (state=initialNavState, action)=>{
let nextState = AppNavigator.router.getStateForAction(action,state);
return nextState || state;
}
You can check this repo https://github.com/JaiDeves/AirBnB-React, I've updated the code with the newer version of react-navigation.

No content in TabNavigator

What could be the reason that content in Tab is not displayed?
I Receive a blank white box.
When I have only export const TopNavTabs without the class App it works but I need this as a component.
import React, { Component } from 'react'
import { Platform, View } from 'react-native'
import { TabNavigator } from 'react-navigation'
import General from './components/tabs/General'
import Help from './components/tabs/Help'
import Tips from './components/tabs/Tips'
export const TopNavTabs = TabNavigator({
General: { screen: General },
Help: { screen: Help },
Tips: { screen: Tips },
},
{
animationEnabled:true
});
export default class App extends Component{
render(){
return(
<View>
<TopNavTabs />
</View>
)
}
}
index.js
import React, {Component} from 'react';
import {AppRegistry, Text, View} from 'react-native';
import App from './src/App';
export default class Test extends Component {
render() {
return (
<App />
);
}
}
AppRegistry.registerComponent('test', () => Test);

React native initalRouteName not working with Stack Navigation

I am new to react-native and I am trying to implement a simple application using StackNavigation and react-redux with welcome and signup screens. I have configured both the screens using StackNavigation but for some reasons , only the SignUp screen pops up when the app starts. Below are my files :
Index.js
import { AppRegistry } from 'react-native';
import App from './App';
AppRegistry.registerComponent('MyApp', () => App);
App.js
import React, { Component } from 'react';
import { Provider, connect } from "react-redux";
import { addNavigationHelpers } from "react-navigation";
import StackNavConfig from "./js/config/routes";
import getStore from "./js/store";
const AppNavigator = StackNavConfig;
const initialState = AppNavigator.router.getActionForPathAndParams('Welcome');
const navReducer = (state = initialState, action) => {
const newState = AppNavigator.router.getStateForAction(action, state);
return newState || state;
};
const AppWithNavigationState = connect(state => ({
nav: state.nav,
}))(({ dispatch, nav }) => (
<AppNavigator navigation={addNavigationHelpers({ dispatch, state: nav })} />
));
const store = getStore(navReducer);
class App extends React.Component {
render() {
return (
<Provider store={store}>
<AppWithNavigationState />
</Provider>
);
}
}
export default App;
js/config/routes.js
import Welcome from "../components/Welcome/view/Welcome";
import SignUp from "../components/SignUp/view/SignUp";
import { StackNavigator } from "react-navigation";
const Routes = {
Welcome: { screen: Welcome , path: ''},
SignUp: { screen: SignUp , path : '/signup'},
};
const RoutesConfig = {
initialRouteName: 'Welcome',
headerMode: 'none',
};
export default StackNavConfig = StackNavigator(Routes, RoutesConfig);
store.js
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import getRootReducer from "./reducers/index";
export default function getStore(navReducer) {
const store = createStore(
getRootReducer(navReducer),
undefined,
applyMiddleware(thunk)
);
return store;
}
Below are my components
Welcome.js
import React from 'react';
import {
View,
Image} from 'react-native';
import { connect } from "react-redux";
import { bindActionCreators } from "redux";
import * as welcomeActions from "../actions/WelcomeActions";
import { welcomeStyles } from '../styles/WelcomeStyles';
class Welcome extends React.Component {
constructor(){
super();
this.state = { };
}
render(){
return (
<View style = {welcomeStyles.mainContainer}>
<Text>Welcome</Text>
</View>
);
}
}
export default connect(
state => ({
}),
dispatch => bindActionCreators(welcomeActions, dispatch)
)(Welcome);
SignUp.js
import React from 'react';
import {
View,
Image} from 'react-native';
import { connect } from "react-redux";
import { bindActionCreators } from "redux";
import * as welcomeActions from "../actions/SignUpActions";
import { signUpStyles } from '../styles/SignUpStyles';
class Welcome extends React.Component {
constructor(){
super();
this.state = { };
}
render(){
return (
<View style = {signUpStyles.mainContainer}>
<Text>SignUp</Text>
</View>
);
}
}
export default connect(
state => ({
}),
dispatch => bindActionCreators(signUpActions, dispatch)
)(SignUp);
I also have action and reducer files for each of my component.But they are blank as of now , since I haven't yet implemented the redux part.I am combining the reducers as below.
import { combineReducers } from "redux";
import welcomeReducer from "../components/Welcome/reducers/WelcomeReducer";
import signUpReducer from "../components/SignUp/reducers/SignUpReducer";
export default function getRootReducer(navReducer) {
return combineReducers({
nav: navReducer,
welcomeReducer : welcomeReducer,
signUpReducer : signUpReducer,
});
}
As mentioned before , even after setting the initialRouteName to Welcome in my routes.js , the SignUp screen appears first everytime I launch the app. Please help
I found out what was the issue. I was calling this.props.navigate inside the render function by mistake which was causing the navigation to different screen.