Initialize react-native application with class components - reactjs

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

Related

Navigation inside class component not working

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

React Native - render a component onClick on an Icon

A part of my app has an 'icon'. When I 'click' on the icon, the State of the parent component changes to 'true' and I want a new 'Component' to render saying 'I am a new Component'. I am trying like this below, there is no error showing at the debugger. The Icon is an image component that I am importing. Here is the Code.
This is the parent Component
import React, {Component} from 'react';
import {View} from 'react-native';
import {Icon} from '../ui/Icon';
type HomeSceneState = {
calendarState:boolean
}
class HomeScene extends Component<HomeSceneState> {
state = {
calendarState:false
}
openCalendar = () => {
console.log("open calendar")
this.setState({
calendarState : true
})
}
render() {
return (
<View style={{marginBottom: spacing.double,
backgroundColor:"black", flexDirection:"row"
}}>
<View>
<Icon onPress = {() => this.openCalendar()} />
{this.calendarState ? <Casie/> : null }
</View>
</View>
);
}
}
export default HomeScene;
The Children Component looks like below
class Casie extends Component<CalendarProps> {
render() {
return (
<View>
I am a new Component
</View>
);
}
}
export default Casie;
replace <Calendar/> by your child component name <Casie/> (in your case). It seems you are not rendering your child component when the state changes.
In your parent component you import the react native navigation.
after you can use useNavigation for navigate the page. Sorry my english.
import { useNavigation } from '#react-navigation/native'
class HomeScene extends Component<HomeSceneState> {
state = {
calendarState:false
}
openCalendar = () => {
console.log("open calendar")
navigation.navigate('Casie')
}
render() {
return (...)
}
}
export default HomeScene;

How to get state of class from another file React-Native

I am trying to get state of a class from another class but it throws an error "cannot read property 'state' od undefined". My approach is when the user press the button the "FromStr" state get redirect to another class B from A. i tried
import React, { Component } from "react";
import { StyleSheet, Text, View, TextInput, Button } from "react-native";
import styles from "./appstyles";
import {getValue} from "./main"
export default class A extends Component{
constructor (props) {
super(props)
this.state={
From:'',
FromStr:'',
}
}
changeText=(From)=>{
this.setState({From})
}
onPress = ()=>{
this.setState({FromStr: this.state.From})
this.fetch()
}
fetch(){
getValue();
}
render(){
return (
<View>
<View style={styles.inputFields}>
<TextInput placeholder="From" id="from" style={styles.fromField} onChangeText={this.changeText} />
<View style={styles.buttonStyle}>
<Button
title={"Go Back"}
color="#f194ff"
onPress={this.onPress}
></Button>
);
}
}
Class B
import React, { Component } from "react";
export function getValue(){
alert(this.state.FromStr);
}
Shared state between components by direct access is an anti-pattern. Each component should have its own state. If you need globally, please consider using Redux.
Passing state as props is also valid, but it only works when components are in parent-child order. Redux allows components to be updated irrelevant of their relationship
As mentioned , pass state as props to their children.
class classname2 extends React.Component {
this.state = { statename1: "lala" };
render() {
return <classname1 statename1={this.state.statename1} />
}
};
class classname1 extends React.Component {
render() {
return (
<div>{this.props.statename1}</div>
);
}
};
You can define class A's this as global inside it's container. Then, call it from class B. For example;
//class A constructor
constructor(props){
super(props);
global.__classAThis = this;
}
//class B constructor
constructor(props){
super(props);
console.log(__classAThis);
//also you can update class A this
__classAthis.setState({test: true})
}
There are many ways to do this. The simplest way is to use LocalStorage .
Usage
A screen
this.setState({FromStr: this.state.From
}, () => localStorage.setItem('FromStr', this.state.From));
B screen
componentDidmount(){
const data = localStorage.getItem('FromStr')
alert(data);
}

Proper way of defining/initializing state in reactjs or react-native

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

Call lifecycle methods on container component created with connect()

I would like to call componentDidMount() on the container component that is created by this connect()ed component:
import { View, Text } from 'react-native'
import { connect } from 'react-redux'
import { formStyles } from '../../style'
import { DimenInput } from '../dimenInput/DimenInput'
import { updateDimension } from '../../actions/updateDimension.action'
import React from 'react'
import { updateVolume } from '../../actions/updateDimension.action'
import calcVol from '../../calcVol'
const mapStateToProps = (state) => ({
height1: state.get('height').get('height1').toString(),
height2: state.get('height').get('height2').toString()
})
const updateHeight = (text, number) => (dispatch, getState) => {
dispatch(updateDimension('height', text, number))
let litres = calcVol(getState())
dispatch(updateVolume(litres))
}
let Height = (props) => (
<View style={formStyles.container}>
<DimenInput
value={props.height1}
onChangeText={text => props.updateHeight(text, 1)}
/>
<Text style={formStyles.text}>{'FT'}</Text>
<DimenInput
value={props.height2}
onChangeText={text => props.updateHeight(text, 2)}
/>
<Text style={formStyles.text}>{'IN'}</Text>
</View>
)
Height.propTypes = {
height1: React.PropTypes.string.isRequired,
height2: React.PropTypes.string.isRequired,
updateHeight: React.PropTypes.func.isRequired
}
Height = connect(
mapStateToProps,
{ updateHeight }
)(Height)
export default Height
Is it possible? I try to use connect() because it does some performance optimisations. Or do I just need to create the container component manually to add lifecycle methods?
The main aim of this is that I need to call a method on app startup. Not on component startup. So if there is another way to do that then I'm interested to know about it. There is a good way to do it with react router onEnter() however I do not have a react router as it is a single page app so no routes.
If you want access to lifecycle methods of a React Component, you'll need to use an object extended from React.Component. You can achieve this by creating your component using React.createClass or ES6 class notation instead of using a functional component like you are dong now with your arrow function.
React top level API
var Height = React.createClass({
componentDidMount: function(){
//...
}
});
ES6 approach:
class Height extends React.Component {
constructor(props) {
//...
}
componentDidMount(){
//...
}
}

Resources