While using class component I cannot use navigation its telling invalid hooks . How can I use navigation inside class component?
this is what i am trying to acheive , navigation option inside class component. actually i a m newbie .Can anyone help me?
import React, { Component } from 'react';
import { Text ,View ,TouchableOpacity } from 'react-native';
import { useNavigation } from '#react-navigation/native';
class Mpin extends Component {
const navigation= useNavigation();
render() {
return (
<Text>....</Text>
<TouchableOpacity onPress={()=>navigation.navigate('LoginPage')}>
<Text>SetMPIN</Text>
</TouchableOpacity>
);
}
}
export default Mpin;
You cannot use hooks inside class component. Inside class component you can directly access navigation object from props.
this.props.navigation.navigate('LoginPage')
Actually I can understand what you are trying to say. I came through this same kind of mistakes when I first started.
Use the below functional component inside of your class component like shown . By doing so you can access navigation inside class component.
import React, { Component } from 'react';
import { Text ,View ,TouchableOpacity } from 'react-native';
import { useNavigation } from '#react-navigation/native';
function ForgotMpin() {
const navigation = useNavigation();
return (
<View>
<TouchableOpacity
style={...}
onPress={() => navigation.navigate("ForgotPin")}
>
<Text>... </Text>
</TouchableOpacity>
</View>
);
}
class Mpin extends Component {
render() {
return (
<Text>....</Text>
<ForgotMpin screenName="forgotMpin" />
);
}
}
export default Mpin;
you can use vanilla js in those cases, the following code helps you redirect or navigate to other paths:
window.locate.replace('/pathname')
if you want to use Navigate or useNavigate you will have to convert to function component and not a class component
Related
I have just installed create-react-native-app and created one. I can see that app is a function there
export default function App() {
return (
<View style={styles.container}>
<Text>Open up App.tsx to start working on your app!</Text>
</View>
);
}
I know that both Functional and Class-Components in available in React. Now I want to create app with Class Components. Can somebody suggest how to do it?
For people who come from heavy object-oriented background, the class-based component will let them jump on reactjs relatively quickly compared to a functional-based component.
Here is some basic skeleton of the class component:
import * as React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
export default class App extends React.PureComponent {
constructor() {
// Where you initialize some data
}
componentDidMount() {
// Lifecycle method when your component is mounted
}
componentWillUnmount() {
// Lifecycle method when your component is unmounted
}
_handleOnButtonPress = () => {
// Handler when your button is pressed
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this._handleOnButtonPress}>
<Text>Open up App.tsx to start working on your app!</Text>
</TouchableOpacity>
</View>
);
}
}
And here is a further reference to compare class and functional component. Cheers!
Here is code for you :
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet
} from 'react-native';
class App extends Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount = () => {
// initial method
};
render() {
return (
<View>
<Text>Test</Text>
</View>
);
}
}
const styles = StyleSheet.create({
});
export default App;
You don't need to make it a class unless you are using state in the class
So far I understand there are two ways to define state in react class.
The first as many people use them, is as follows:
import React, { Component } from "react";
import { View, Text } from "react-native";
export default class Test extends Component {
constructor (props) {
super(props)
this.state = {
text: 'hello'
}
}
render() {
return (
<View>
<Text>{this.state.text}</Text>
</View>
);
}
}
The second one is as follows:
import React, { Component } from "react";
import { View, Text } from "react-native";
export default class Test extends Component {
state = {
text: "hello"
}
render() {
return (
<View>
<Text>{this.state.text}</Text>
</View>
);
}
}
The difference is at using constructor or not. What is the effect and is there any difference at all between the two? If there is, which one should I use?
Thank you!
Both methods are correct. Make sure you have support for class properties enabled in the babelrc. If you are using CRA both will work. Constructor one is better on the eyes if you want to seed the initial state from props.
Both methods are fine. Second one is the short-hand method
I want to use React.memo for optimization in react native.
import React from "react";
import { View, Text } from "react-native";
const Memo = React.memo(function() {
return (
<View>
<Text>Ok</Text>
</View>
);
});
class Demo extends React.Component {
render() {
return <Memo />;
}
}
export default Demo;
It gives following error:
TypeError : undefined is not a function (evaluating render(nextProps)).
This error is located at :
in Demo(at renderApplication.js:34)
in RCTView(at View.js:44 )
Can we use React.memo in react native?
The "component" you are trying to memoize isn't a correct react component, it isn't being passed any props. The react memo HOC is also only for functional components, use PureComponent for class-based components
You need to ensure you are using the current version of react that introduced the memo HOC, and use it as such:
import React, { Component, memo } from "react";
import { View, Text } from "react-native";
const Demo = props => (
<View>
<Text>Ok</Text>
</View>
);
export default memo(Demo); // memo HOC memoizes return component based on state and props!
React memo
const MyFunctionComponent = ({text}) => <Text>{text}</Text>;
MyFunctionComponent.displayName = 'HarmlessComponent';
MyFunctionComponent.propTypes = {text: PropTypes.string.isRequired};
export default React.memo(MyFunctionComponent);
I'm dynamically building my "screen" with the use of child "row" and "button" components. I'm only using this method because I can't find a flex-flow property available for react-native.
So basically I'm mapping through an array of arrays to build each row, and within the row, mapping through each array to build each button. Because the onPress needs to be set in the button, I'm passing the URL for each
onPress{() => this.props.navigation.navigate({navigationURL})
as a prop, first to the row, and then to the button. The problem is I keep getting the error 'Cannot read property 'navigation' of undefined. I'm sure this is because only the actual "screens" within the navigator have access to the navigation props. I've also tried passing
navigation={this.props.navigation}
but had no success. I've looked through all of the documentation and can't seem to find anything helpful. Anyone else encountered a similar situation?
If you want to access the navigation object from a component which is not part of navigator, then wrap that component in withNavigation HOC. Within the wrapped component you can access navigation using this.props.navigation. Take a look at the official document
Sample
import { withNavigation } from 'react-navigation';
...
class CustomButton extends React.Component {
render() {
return <Button title="Back" onPress={() => {
this.props.navigation.goBack() }} />;
}
}
export default withNavigation(CustomButton);
Hope this will help!
Ahhh, silly mistake. I wasn't setting up Props in the constructor. Thank you Prasun Pal for the help! Here's my code if someone else has an issue.
import React, { Component } from 'react'
import { Image, Text, TouchableOpacity, View } from 'react-native'
import { withNavigation } from 'react-navigation'
class ButtonName extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<TouchableOpacity
onPress={() => this.props.navigation.navigate('PageName')}
>
</TouchableOpacity>
)
}
}
export default withNavigation(ButtonName);
This is my currently working login page. Everything works fine
import React, { Component } from 'react';
import {AlertIOS , StyleSheet , View , Text} from 'react-native';
import Button from 'react-native-button';
import {Actions } from 'react-native-router-flux';
class Login extends Component {
render() {
return (
<View>
<Text>Hello world this is login page</Text>
<Button onPress={Actions.login2}>Click </Button>
</View>
);
}
}
export default Login;
However, I want to call function first for check the username and password.If it's correct I want to go to next screen. How can i achieve this. Like this code below. My real problem is I couldn't figure out calling Actions.ROUTE_NAME method outside of the render method.
//This is not working
import React, { Component } from 'react';
import {AlertIOS , StyleSheet , View , Text} from 'react-native';
import Button from 'react-native-button';
import {Actions } from 'react-native-router-flux';
class Login extends Component {
controlMethod(){
if(true){Actions.login2}
}
render() {
return (
<View>
<Text>Hello world this is login page</Text>
<Button onPress={this.controlMethod}>Click </Button>
</View>
);
}
}
export default Login;
maybe you can try this one :
controlMethod(){
if(true){ Actions.login2() }
}
let's try using ()
hope it can solve you're problem :)
Rizal is right, in your second example, you passed in controlMethod function to the onPress prop, when you click on <Button> component, the controlMethod will get executed, but in your second example the controlMethod will not actually execute the Actions.login2 function but instead it will return the function expression, so to make it work, you want to actually invoke the Actions.login2 which is why you need another pair of parenthesis after the Actions.login2 just like Rizal's example shows.
Also, make sure you bind your controlMethod in your constructor or you can make it a static method instead.