React Native - Unable to get TabNavigator to Work - reactjs

I installed react-navigation and got a Switch Navigator to work, but I am unable to get a Tab Navigator to work. When I compile, I get this error:
Warning: isMounted(...) is deprecated in plain JavaScript React
classes. Instead, make sure to clean up subscriptions and pending
requests in componentWillUnmount to prevent memory leaks.
Then when I dismiss the error, I get a blank screen. My compiler doesn't detect any syntax errors.
import React, { Component } from "react";
import { View, StyleSheet } from "react-native";
import { MainFeed, Login, Camera, Profile } from "./components/screens";
import { SwitchNavigator, TabNavigator } from "react-navigation";
const Tabs = TabNavigator({
feed: MainFeed,
camera: Camera,
profile: Profile
});
const MainStack = SwitchNavigator({
login: Login,
main: Tabs
});
class InstaClone extends Component {
render(){
return <MainStack/>;
}
}
export default InstaClone;

Related

Deep linking in IOS with react navigation does not route to the correct screen?

I have set up deep linking in my project with react-navigation. It is successfully working in android. But in ios, it is opening the app successfully but does not route to the correct location.
this is how I code it with react-navigation.
import 'react-native-gesture-handler';
import * as React from 'react';
import {NavigationContainer} from '#react-navigation/native';
import {Linking} from 'react-native';
import AppStackNavigator from '_navigations/AppStackNavigator';
import I18n from 'i18n-js';
export default function App() {
const linking = {
prefixes: ['https://mydomain/meeting','myapp://meeting'],
config: {
screens: {
login: 'login/:data',
},
},
};
return (
<NavigationContainer linking={linking} >
<AppStackNavigator />
</NavigationContainer>
);
}
As this one is not working then I tried it with getInitialState using use linking hook. Then the initial state was always undefined. I do not have any idea to fix this. I tried almost all the examples I was able to find to fix this issue. But I was unable to do so. If someone can help me to fix this it is really really grateful. Thank you.
react-navigation:"^5.2.16",
react:"16.11.0"
react-native:"0.62.2"
ios:14.2
xcode: 12

The AppNavigator is not exporting the required page

My SplashScreen page is not being exported by the AppNavigator even though the variable is declared and read, on the SplashScreen page.
I have tried to use createDrawerNavigator but I get the same result. I have tried to reset the cache with:
rm -rf node_modules && npm install
npm start -- --reset-cache
I have tried to reInstall the createDrawerNavigator
The error is below:
Unable to resolve module `./navigation/AppNavigator` from
`/Users/jaseyacey/Desktop/beermeapp4/screens/Splash.Screen.js`:
The module `./navigation/AppNavigator` could not be found from
`/Users/jaseyacey/Desktop/beermeapp4/screens/Splash.Screen.js`.
Indeed, none of these files exist:
The SplashScreen code is below:
import React, {Component } from 'react';
import {Image, View } from 'react-native';
import { inject } from 'mobx-react';
import AppNavigator from './navigation/AppNavigator';
import { createDrawerNavigator } from 'react-navigation-drawer';
#inject("stores")
class SplashScreen extends Component {
constructor(props) {
super(props)
}
componentDidMount() {
const {stores, navigation } = this.props;
setTimeout(() => {
navigation.navigate("Login")
}, config.store.SplashTime )
}
render() {
const { stores } = this.props
return (
<View style={{flex: 1}}>
<image style={{flex: 1, width: null, height: null}} source= {config.store.SplashImg}/>
</View>
)
}
}
export default AppNavigator;
You should add you Splash Screen into your App Navigator and there you will create an App Container with your navigation type (drawer navigation in this case) and export the App Navigator containing your splash Screen as your first screen of navigation.
I don't have a Splash Screen on my project yet, but you can see how I configured my App Navigation here: https://github.com/pahferreira/destetik-mobile/blob/master/src/navigation/AppNavigation.js
Or you can check here on their documentation: https://reactnavigation.org/docs/en/hello-react-navigation.html

referencing constants and variables across separate class files

My App.js file was getting very large, so I decided to move out all my classes to their own separate file, and this is what remains in my App.js
import React from 'react';
import {
AppRegistry,
Text,
View,
Button,
Image
} from 'react-native';
import { StackNavigator } from 'react-navigation';
import { TabNavigator } from 'react-navigation';
//screen imports
import RecentChatScreen from './RecentChatScreen';
import AllContactsScreen from './AllContactsScreen';
import ChatScreen from './ChatScreen';
import HomeScreen from './HomeScreen';
import InfoScreen from './InfoScreen';
const MainScreenNavigator = TabNavigator({
Home: { screen: HomeScreen },
Recent: { screen: RecentChatsScreen },
All: { screen: AllContactsScreen },
});
const NavTest = StackNavigator({
Home: { screen: MainScreenNavigator },
Chat: { screen: ChatScreen },
Info: { screen: InfoScreen }
});
I think that looks fine.
However in some of the class files, I need to reference those other screens in button events, like this:
onPress={ () => navigate('Home')}
This worked fine before when everything was in App.js, but how would I reference these screens(Home, Chat, Info, Recent, All) now in the their separate files when the definitions are in App.js?
Thanks!
You can export them in App.js:
// App.js
// ...
export {
MainScreenNavigator,
NavTest,
}
And then import them from it:
import {MainScreenNavigator, NavTest} from './path/to/App.js';
If your intent is just to navigate to the different screens, and not use any properties defined within a particular screens class, then you would not need to import anything. When you define the StackNavigator and lets say you are passing in that value into the AppRegistry as the entry point of the application. In your case, it could be something like this:
AppRegistry.registerComponent('NavTest', () => NavTest)
Now within any of the screens, the navigatation object is passed in as a prop. You can then use that to navigate to any of the defined screens. The initial setup of the StackNavigator is essentially a mapping from a routeName to a react component (a class). So when you want to navigate to a particular class, all you need is the name of the route not the class or component it represents, the navigator already has all that. This name would be the key passed into the StackNavigator for a particular screen. In your example, the routeNames are Home, Chat and Info. So just doing something like this would work:
const { navigate } = this.props.navigation;
return (
<View>
<Text>Navigate Test</Text>
<Button onPress={() => navigate('Chat')} title="Go to chat"/>
</View>
);

React Router Redux - Prompt before hard transition to another domain

Want to trigger an alert or console log before the user navigates to a new domain. From the docs, setRouteLeaveHook or onLeave should work. I followed these directions.
import React from 'react'
import { withRouter } from 'react-router'
const Page = withRouter(
React.createClass({
componentDidMount() {
this.props.router.setRouteLeaveHook(this.props.route, this.routerWillLeave)
},
routerWillLeave(nextLocation) {
console.log("Moved to different domain");
return 'Your work is not saved! Are you sure you want to leave?'
},
render() {
return Redirect
}
})
)
export default Page
Page is the top level component in my app. Using react-router v3 with redux.
How can I trigger an alert before the user leaves our site?
Add the withRouter HOC wrapper on your export like this:
export default withRouter(Page);

RaisedButton not working at all

I have included material-ui (and react-tap-event-plugin) in my project and added 3 buttons to one of my components:
<RaisedButton onClick={this.props.onSave} label="Save" style={styles.button}/>
<RaisedButton label='Publish' onClick={this.props.onPublish} style={styles.button}/>
<RaisedButton label='Cancel' onClick={this.onCancel.bind(this)} style={styles.buttonCancel}/>
when I click on any of these, they go very dark grey and when I click again, they go black (and stay like that). The whole applications goes bonkers, the react routing no longer works (I can see the URL changing in the address bar, but the view doesn't refresh). This all looks pretty bad for a button click :)
Any idea what I may be doing wrong? (I take care of the childContext as described in the docs, so the muiTheme is loaded).
I forgot to check the console... there are 3 exceptions whenever I press the button:
1)
vendor.js:12 Uncaught Error: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's render method, or you have multiple copies of React loaded (details: https://facebook.github.io/react/warnings/refs-must-have-owner.html).(…)
2)
ReactTransitionGroup.js:176 Uncaught TypeError: Cannot read property 'componentWillLeave' of undefined(…)
3)
vendor.js:12 Uncaught Error: removeComponentAsRefFrom(...): Only a ReactOwner can have refs. You might be removing a ref to a component that was not created inside a component's render method, or you have multiple copies of React loaded (details: https://facebook.github.io/react/warnings/refs-must-have-owner.html).(…)
In the component that uses FlatButton (or RaisedButton neither work) I have this:
1) Import:
import FlatButton from 'material-ui/FlatButton'; //eslint-disable-line
import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
2) in the class
getChildContext() {
return { muiTheme: getMuiTheme(baseTheme) };
}
3) and a static declaration:
EditorComponent.childContextTypes = {
muiTheme: React.PropTypes.object.isRequired,
};
Feels like I'm doing all that's required.
This may be related to what I'm experiencing:
https://github.com/callemall/material-ui/issues/2818
So probably the issue is caused by material-ui distributing it's own version of React? What's the point in that? But... my version of material-ui doesn't have a node_modules folder, so no extra React either...
Source for a component importing and using FlatButton
import React from 'react'; // eslint-disable-line
import Input from '../../../components/common/textInput'; // eslint-disable-line
import BaseEditorComponent from '../base/EditorComponent';
import FlatButton from 'material-ui/FlatButton'; //eslint-disable-line
import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
export default class EditorComponent extends BaseEditorComponent {
constructor() {
super();
this.state = {
textValue: 'Enter value'
};
}
getChildContext() {
return { muiTheme: getMuiTheme(baseTheme) };
}
_onChange(e) {
this.setState({
textValue: e.target.value
});
}
render() {
return (
<div>
<Input
value={this.state.textValue}
name="SimpleText"
label="Simple Text Value:"
onChange={this._onChange.bind(this)}
/>
<FlatButton label="Test"/>
</div>
);
}
}
EditorComponent.childContextTypes = {
muiTheme: React.PropTypes.object.isRequired,
};
Also, the BaseEditorComponent:
import React from 'react';
import widgetActions from '../../widgets/WidgetActions';
import widgetInstanceStore from '../../widgets/WidgetInstanceStore';
export default class EditorComponent extends React.Component {
constructor() {
super();
}
componentDidMount() {
this.setState(widgetInstanceStore.getWidgetInstanceState(this.props.widgetId) || {});
}
save() {
widgetActions.saveWidgetInstanceState(this.props.widgetId, this.state);
}
}
Have you tried to use onTouchTap instead of onClick?
If #1 doesn't help, please show more code - component with above code and it's parent component.
As per https://github.com/callemall/material-ui/issues/2818 the solution was to include react-addons-transition-group alongside react in the browserify bundle. So it's good to know that it's not only NPM where a 2nd copy of react can slip through, but also browserify or webpack.
Thanks https://stackoverflow.com/users/3706986/piotr-sołtysiak for helping with the issue today!

Resources