React-Native Navigator is deprecated and has been removed from this package - react-native

I get the following error.
Navigator is deprecated and has been removed from this package. It can now be installed and imported from react-native-deprecated-custom-components instead of react-native. Learn about alternative navigation solutions at http://facebook.github.io/react-native/docs/navigation.html
Then I would update react-native-deprecated-custom-components package but issue not solved
Package.Json
"dependencies": {
"react": "16.0.0-alpha.6",
"react-native": "0.44.2",
"react-native-deprecated-custom-components": "^0.1.0",
"sendbird": "^3.0.30"
},
main.js
var React = require('react-native')
var {
Navigator,
StyleSheet
} = React;
var Login = require('./components/login');
import NavigationExperimental from 'react-native-deprecated-custom-components';
var ROUTES = {
login: Login
};
module.exports = React.createClass({
renderScene: function(route, navigator) {
var Component = ROUTES[route.name];
return <Component route={route} navigator={navigator} />;
},
render: function() {
return (
<NavigationExperimental.Navigator
style={ styles.container }
initialRoute={ {name: 'login'} }
renderScene={this.renderScene}
configureScene={ () => { return Navigator.SceneConfigs.FloatFromRight; } }
/>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1
}
});
Any one let me know to solve this issue

Ive use below code to fix my issue
main.js
var React = require('react-native')
var {
Navigator,
StyleSheet
} = React;
var Login = require('./components/login');
import NavigationExperimental from 'react-native-deprecated-custom-components';
var ROUTES = {
login: Login
};
module.exports = React.createClass({
renderScene: function(route, navigator) {
var Component = ROUTES[route.name];
return <Component route={route} navigator={navigator} />;
},
render: function() {
return (
<NavigationExperimental.Navigator
style={ styles.container }
initialRoute={ {name: 'login'} }
renderScene={this.renderScene}
configureScene={ () => { return NavigationExperimental.Navigator.SceneConfigs.FloatFromRight; } }
/>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1
}
});
Any one let me know to solve this issue
I've change the lines
configureScene={ () => { return NavigationExperimental.Navigator.SceneConfigs.FloatFromRight; } }
To
configureScene={ () => { return NavigationExperimental.Navigator.SceneConfigs.FloatFromRight; } }
Fix my issue

You should use Stack Navigator now
import { StackNavigator } from 'react-navigation';
const SimpleApp = StackNavigator({
Home: { screen: HomeScreen },
Chat: { screen: ChatScreen },
});
<Button
onPress={() => navigate('Chat')}
title="Chat with Lucy"
/>
reference : https://reactnavigation.org/docs/intro/

If anyone is seeing this while not even trying to use Navigator, it’s possibly because you’ve got an import line like
import * as RN from 'react-native'
(Webstorm in particular has a habit of auto-inserting these)
This calls the getters for all of RN’s exports, triggering the error for Navigator. Instead use:
import {Things, You, Need} from 'react-native'

Related

How to call hook in class component in React Native?

Tech used
React Native Appearance, Typescript & Redux Rematch.
Problem
I am attempting to pass my customized theme colours into a class component. I also understand that hooks cannot be used/called within a class component and only a functional component. The reason why I am using a class component is because of Redux Rematch. Is there a way for me to get my colours from the hook listed below into my class component?
This is how I am building my theme:
index.tsx
const palette = {
colourTextDark: "#ffffff",
colourTextLight: "#000000",
};
export const colors = {
colourText: palette.colourTextLight,
};
export const themedColors = {
default: {
...colors,
},
light: {
...colors,
},
dark: {
...colors,
colourText: palette.colourTextDark,
},
};
hooks.tsx
import { useColorScheme } from "react-native-appearance";
import { themedColors } from "./";
export const useTheme = () => {
const theme = useColorScheme();
const colors = theme ? themedColors[theme] : themedColors.default;
return {
colors,
theme,
};
};
Ideally I would want to use it like so:
import { useTheme } from "../../theme/hooks";
...
class Example extends React.Component<Props> {
render() {
// This doesn't work
const { colors } = useTheme();
return (
<Text style={{ color: colors.colourText }}>Please help :)</Text>
)
}
}
How would I be able to do this? Thanks in advance :)
You could create a high order component like this:
const themeHOC = (Component) => {
return (WrappedComponent = (props) => {
const { colors } = useTheme();
return <Component {...props} colors={colors} />;
});
};
And use it like this:
themeHOC(<Example />)
This worked for me.
componentDidMount() {
(async () => {
const theme = useColorScheme() === "dark" ? styles.dark : styles.light;
this.setState({ theme });
})();
this.sendEmail();
}

How to stop Fast refresh reset route to initialRoute automatically in React Native

How are you.
I am using React Native 0.62.2.
The problem is when code updated, it goes to initalRoute automatically, so I need to navigate to screen I was working to check updated.
How can I stop it so when updated code, fast refresh shows update on current screen?
"react": "16.11.0",
"react-native": "0.62.2",
"#react-navigation/bottom-tabs": "^5.2.7",
"#react-navigation/drawer": "^5.5.0",
"#react-navigation/material-bottom-tabs": "^5.1.9",
"#react-navigation/native": "^5.1.5",
"#react-navigation/stack": "^5.2.10",
Thanks
For those who are running into this problem with React Native Web.
I fixed this by configuring Linking with React Navigation.
const config = {
screens: {
Login: 'login',
Home: '',
About: 'about',
},
};
const linking = {
prefixes: ['https://example.com',],
config,
};
<NavigationContainer linking={linking}>
...
</NavigationContainer>
Once Linking was set up, fast refresh no longer reseted the navigation to the first route.
You can write a component that record the state of the navigation and stores it on asyncStorage. Maybe something like so:
import { InitialState, NavigationContainer } from "#react-navigation/native";
import React, { useCallback, useEffect, useState } from "react";
import { AsyncStorage } from "react-native";
const NAVIGATION_STATE_KEY = `NAVIGATION_STATE_KEY-${sdkVersion}`;
function NavigationHandler() {
const [isNavigationReady, setIsNavigationReady] = useState(!__DEV__);
const [initialState, setInitialState] = useState<InitialState | undefined>();
useEffect(() => {
const restoreState = async () => {
try {
const savedStateString = await AsyncStorage.getItem(
NAVIGATION_STATE_KEY
);
const state = savedStateString
? JSON.parse(savedStateString)
: undefined;
setInitialState(state);
} finally {
setIsNavigationReady(true);
}
};
if (!isNavigationReady) {
restoreState();
}
}, [isNavigationReady]);
const onStateChange = useCallback(
(state) =>
AsyncStorage.setItem(NAVIGATION_STATE_KEY, JSON.stringify(state)),
[]
);
if (!isNavigationReady) {
return <AppLoading />;
}
return (
<NavigationContainer {...{ onStateChange, initialState }}>
{children}
</NavigationContainer>
);
}
I'd check LoadAsset Typescript component from #wcandillon here
Maybe you can try this way.
I follow the State persistence document of React Navigation to write the code down below.
https://reactnavigation.org/docs/state-persistence/
import * as React from 'react';
import { Linking, Platform } from 'react-native';
import AsyncStorage from '#react-native-community/async-storage';
import { NavigationContainer } from '#react-navigation/native';
const PERSISTENCE_KEY = 'NAVIGATION_STATE';
export default function App() {
const [isReady, setIsReady] = React.useState(__DEV__ ? false : true);
const [initialState, setInitialState] = React.useState();
React.useEffect(() => {
const restoreState = async () => {
try {
const initialUrl = await Linking.getInitialURL();
if (Platform.OS !== 'web' && initialUrl == null) {
// Only restore state if there's no deep link and we're not on web
const savedStateString = await AsyncStorage.getItem(PERSISTENCE_KEY);
const state = savedStateString ? JSON.parse(savedStateString) : undefined;
if (state !== undefined) {
setInitialState(state);
}
}
} finally {
setIsReady(true);
}
};
if (!isReady) {
restoreState();
}
}, [isReady]);
if (!isReady) {
return <ActivityIndicator />;
}
return (
<NavigationContainer
initialState={initialState}
onStateChange={(state) =>
AsyncStorage.setItem(PERSISTENCE_KEY, JSON.stringify(state))
}
>
{/* ... */}
</NavigationContainer>
);
}

Uhandled atob variable on screen rendering

The error I get is [Unhandled promise rejection: ReferenceError: Can't find variable: atob].
And my screen code:
import React, { Component } from "react";
import { View, StatusBar, Text } from "react-native";
import firebase from "firebase";
import "firebase/firestore";
import { RowItem } from "../components/RowItem";
import { Header, Left, Right, Icon } from "native-base";
const styles = {
container: {
flexDirection: "row",
flexWrap: "wrap",
padding: 20
}
};
class QuizIndex extends Component {
constructor(props) {
super(props);
this.state = {
docs: []
};
}
async componentDidMount() {
await this.quizes();
}
quizes = async () => {
let result = await firebase
.firestore()
.collection("quiz")
.where("parentId", "==", "")
.get()
.then(r => {
console.log("fine");
})
.catch(e => {
console.log("Not fine");
});
const docs = result.docs.map(doc => {
return { uid: doc.id, ...doc.data() };
});
return this.setState({ docs });
};
render() {
return (
<View style={styles.container}>
<StatusBar barStyle="dark-content" />
{this.state.docs.map(doc => (
<RowItem
key={doc.uid}
parentId={doc.parentId}
name={doc.title}
color={doc.color}
icon={doc.icon}
onPress={() =>
this.props.navigation.navigate("QuizSub", {
title: doc.title,
color: doc.color,
parentId: doc.uid
})
}
/>
))}
</View>
);
}
}
export default QuizIndex;
I don't get it where this problem occur because the things were working fine. Do you have any suggestion about this ? I googled it but none of the solutions helped me.
It's an issue in firebase dependency
Try to use version 7.9.0, this version will work fine.
yarn add firebase#7.9.0
I think if you install the base-64 npm package it will solve, but don't quite know why this is happening.
yarn add base-64
#or
npm install base-64
At App.js add:
import {decode, encode} from 'base-64'
if (!global.btoa) { global.btoa = encode }
if (!global.atob) { global.atob = decode }

Change tabBarIcon when a redux state changes

I have defined navigationOptions under App.js for a flow like so:
App.js
const intimationsFlow = createStackNavigator({
Feed: FeedContainer,
Edit: EditContainer
});
intimationsFlow.navigationOptions = ({ navigation }) => {
let tabBarVisible = true;
if (navigation.state.index > 0)
tabBarVisible = false;
return {
title: '',
tabBarIcon: ({ focused }) => {
const { pushNotificationSeen } = store.getState();
console.log('pushNotificationSeen', pushNotificationSeen);
let i;
if(pushNotificationSeen) {
if (focused) {
i = <FontAwesomeIcon icon={'bell'} size={29} color={'#3780BE'} />
} else {
i = <FontAwesomeIcon icon={'bell'} size={29} color={'#393939'} />
}
} else {
if (focused) {
updatePushNotificationSeen(true);
i = <FontAwesomeIcon icon={'bell'} size={29} color={'#3780BE'} />
} else {
i = <><FontAwesomeIcon icon={'bell'} size={29} color={'#393939'} /><Badge status="error" badgeStyle={{ position: 'absolute', top: -26, right: -13 }} /></>
}
}
return i;
},
tabBarVisible
};
};
const AppNavigator = createSwitchNavigator({
ResolveAuth: ResolveAuthScreen,
mainFlow
});
const App = createAppContainer(AppNavigator);
export default () => {
return <Provider store={store}>
<SafeAreaProvider>
<App ref={navigatorRef => { setTopLevelNavigator(navigatorRef) }} />
</SafeAreaProvider>
</Provider>
};
I want to update the tabBarIcon based on whether a push notification has already been seen or not. If the push notification has not already been seen then I show a badge instead.
The problem here is that I could only fetch the state when there is an activity on the tab bar. But what I want is that whenever the status of pushNotificationSeen is updated, the tarBarIcon should get re-rendered.
Please suggest if it is possible otherwise how could it be achieved. Thanks.
you have to listen push notifications change in reducer at componentWillReceiveProps
class YourComponent extends React.Component {
{...}
static navigationOptions = {
title: ({ state }) => `there is ${state.params && state.params.pushNotificationSeen ? state.params.pushNotificationSeen : ''}`,
{...}
}
{...}
componentWillReceiveProps(nextProps) {
if (nextProps.pushNotificationSeen) {
this.props.navigation.setParams({ pushNotificationSeen });
}
}
}
const connectedSuperMan = connect(state => ({ pushNotificationSeen: state.ReducerYo.pushNotificationSeen }))(YourComponent);
I was able to find a decent solution.
What really I wanted was a way to access redux store from the React Navigation component. React navigation components like any other react components can be connected to the redux store. However, in this particular case, in order to connect the react navigation component, what I wanted was to create an custom extended navigator as per this suggestion.
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Badge } from 'react-native-elements';
import { createStackNavigator } from 'react-navigation-stack';
import { FontAwesomeIcon } from '#fortawesome/react-native-fontawesome';
import { NavigationEvents } from 'react-navigation';
import FeedContainer from '../../screens/feed/FeedContainer';
import EditContainer from '../../screens/edit/EditContainer';
import { updatePushNotificationSeen } from '../../store/push-notification-seen/actions';
const IntimationsFlow = createStackNavigator({
Feed: FeedContainer,
Edit: EditContainer
});
class IntimationsFlowNavigator extends Component {
static router = IntimationsFlow.router;
static navigationOptions = ({ navigation }) => {
let tabBarVisible = true;
if (navigation.state.index > 0)
tabBarVisible = false;
return {
title: '',
tabBarIcon: ({ focused }) => {
let i;
if (!navigation.state.params || navigation.state.params.pushNotificationSeen) {
if (focused)
i = <FontAwesomeIcon icon={'bell'} size={29} color={'#3780BE'} />;
else
i = <FontAwesomeIcon icon={'bell'} size={29} color={'#393939'} />;
} else {
if (focused)
i = <FontAwesomeIcon icon={'bell'} size={29} color={'#3780BE'} />;
else
i = <>
<FontAwesomeIcon icon={'bell'} size={29} color={'#393939'} />
<Badge status="error" badgeStyle={{ position: 'absolute', top: -26, right: -13 }} />
</>;
}
return i;
},
tabBarVisible
};
};
componentDidUpdate(prevProps) {
const { navigation, pushNotificationSeen } = this.props;
if (pushNotificationSeen !== prevProps.pushNotificationSeen)
navigation.setParams({ pushNotificationSeen });
}
render() {
const { navigation } = this.props;
return <>
<NavigationEvents
onDidFocus={() => { if (!this.props.pushNotificationSeen) updatePushNotificationSeen(true) }}
onDidBlur={() => { if (!this.props.pushNotificationSeen) updatePushNotificationSeen(true) }}
/>
<IntimationsFlow navigation={navigation} />
</>;
}
}
const mapStateToProps = ({ pushNotificationSeen }) => {
return { pushNotificationSeen };
};
export default connect(mapStateToProps, null)(IntimationsFlowNavigator);
Every time there was an update in the props. I was setting new value for navigation.state.params.pushNotificationSeen like so navigation.setParams({ pushNotificationSeen }); in the componentDidUpdate lifecycle method so as to use it in the navigationOptions static method. (We can't directly access components props in the navigationOptions method since it is a static member).
Any side-effects that are needed to be performed on focus/blur of the tab can be achieved via NavigationEvents as per this suggestion.

bundling failed: SyntaxError in D:\RN\AtmosphericMeshing-\src\router.js: D:/RN/AtmosphericMeshing-/src/router.js: Unexpected token (16:0)

everyone, I have been reporting wrong when I used the react-native compilation project, I don't know how to solve it, I can't find the error, please give me some Suggestions, thank you very much.
import React, { PureComponent } from 'react';
import { BackHandler, Platform, View, StatusBar, Text,Modal } from 'react-native';
import {
addNavigationHelpers
} from 'react-navigation';
import { connect } from 'react-redux';
import moment from 'moment';
import SplashScreen from 'react-native-splash-screen';
import { loadToken, getNetConfig, saveNetConfig, loadNetConfig } from './dvapack/storage';
import { createAction, NavigationActions, getCurrentScreen } from './utils';
import NetConfig from './config/NetConfig.json';
import api from './config/globalapi';
import AppNavigator from './containers/';
*I don't know if this is the correct way of writing the router, and it has led to this problem.*
#connect(({ router }) => ({ router }))***//一直报这里的错误=I've been making mistakes here.***
class Router extends PureComponent {
constructor(props) {
super(props);
this.state = {
configload: true
};
}
async componentWillMount() {
let netconfig =await loadNetConfig();
if (!netconfig && !netconfig != null) {
if (NetConfig.isAutoLoad) {
const newconfig = [];
NetConfig.Config.map((item, key) => {
const netitem = {};
// netitem.neturl = `http://${item.configIp}:${item.configPort}`+api.appurl;
netitem.neturl = `http://${item.configIp}:${item.configPort}`;
if (key === 0) {
netitem.isuse = true;
} else {
netitem.isuse = false;
}
newconfig.push(netitem);
});
saveNetConfig(newconfig);
} else {
this.setState({ configload: false });
SplashScreen.hide();
}
}
BackHandler.addEventListener('hardwareBackPress', this.backHandle);
}
async componentDidMount() {
const user = await loadToken();
this.props.dispatch(createAction('app/loadglobalvariable')({ user }));
}
componentWillUnmount() {
if (Platform.OS === 'android') {
BackHandler.removeEventListener('hardwareBackPress', this.backHandle);
JPushModule.removeReceiveCustomMsgListener(receiveCustomMsgEvent);
JPushModule.removeReceiveNotificationListener(receiveNotificationEvent);
JPushModule.removeReceiveOpenNotificationListener(openNotificationEvent);
JPushModule.removeGetRegistrationIdListener(getRegistrationIdEvent);
JPushModule.clearAllNotifications();
} else {
DeviceEventEmitter.removeAllListeners();
NativeAppEventEmitter.removeAllListeners();
}
}
backHandle = () => {
const currentScreen = getCurrentScreen(this.props.router);
//登录
if (currentScreen === 'Login') {
return true;
}
if (currentScreen !== 'Home') {
this.props.dispatch(NavigationActions.back());
return true;
}
return false;
}
render() {
if (!this.state.configload) {
return (
<View style={{ flex: 1 }}>
<StatusBar
barStyle="light-content"
/>
{/* <ScanNetConfig ScanSuccess={() => {
this.setState({ configload: true });
}}
/> */}
<Text>ScanNetConfig</Text>
</View>
);
}
const { dispatch, router } = this.props;
const navigation = addNavigationHelpers({ dispatch, state: router });
return (
<View style={{ flex: 1 }}>
<AppNavigator navigation={navigation} />
</View>
);
}
}
export function routerReducer(state, action = {}) {
return AppNavigator.router.getStateForAction(action, state);
}
export default Router;
Need More Detail?
this is the error.
bundling failed: SyntaxError in D:\RN\AtmosphericMeshing-\src\router.js: D:/RN/AtmosphericMeshing-/src/router.js: Unexpected token (16:0)
I find the Solution
.babelrc needs to be changed:
{
"presets": ["react-native"],
"plugins": [
"syntax-decorators",
"transform-decorators-legacy",
["import", { "libraryName": "antd-mobile" }]
]
}