function componentDidMount not firing in react native - react-native

The function componentDidMount is not firing.
This is some of my code:
import React, { Component } from 'react';
import { Block } from 'galio-framework';
export function FriendRequests ( ) {
const username = 'abcd';
componentDidMount = () => {
alert("abcd");
}
return (
line number 37: <Block>....</Block>
)
}

You are using the functional component which doesn't have the lifecycle methods.
Solution 1:
import React, { Component } from 'react';
import { View, Text } from 'react-native';
class FriendRequests extends Component {
constructor(props) {
super(props);
this.state = {
};
}
componentDidMount = () => {
alert("abcd");
}
render() {
return (
<View>
<Text> Your text Here </Text>
</View>
);
}
}
export default FriendRequests;
Solution 2:
If you want to use it as functional component then you can use the React Hook and can make use of useEffect() method from the hook instead of componentDidMount. method to handle after render stuff.

First of all,
export function FriendRequests ( ) {
componentDidMount = () => {
alert("abcd");
}
return (
....
)
}
this is a functional component, and functional component dont have any inbuilt functions like componentDidMount. Only class based components have access, So try this:
UPDATE:
export class FriendRequests extends React.Component {
componentDidMount() {
alert("abcd");
}
render() {
return (
<View>
<Text>hey</Text>
</View>
);
}
}
hope it helps. feel free for doubts

Related

useTheme equivalent for class component

I would like to use the current theme in my class component.
According to the latest (RN 5.x) documentation, there is a useTheme() hook for that purposes. However, it doesn't mention any class equivalent.
I found ThemeContext.Consumer in RN 4.x but it is not available in 5.x anymore.
Is it possible to achieve the effect of useTheme() in some other way for a class component?
This is not so elegant, but it will do the job for you.
Here is my method to access the theme inside a class component:
import React from 'react'
import { SafeAreaView, Text } from 'react-native'
import { useTheme } from '#react-navigation/native'
export default class Home extends React.Component {
constructor(props) {
super(props)
this.state = {
theme: undefined
}
}
setTheme = theme => {
this.setState({theme})
}
render () {
console.log('theme', this.state.theme)
return (
<SafeAreaView>
<SetTheme setTheme={this.setTheme} />
<Text>Hello world</Text>
</SafeAreaView>
)
}
}
const SetTheme = ({ setTheme }) => {
const theme = useTheme()
React.useEffect(() => {
setTheme(theme)
return () => null
},[])
return null
}

How to get Element Properties in React Native on a Click Event

How should I access the properties of an element without using the 'this' keyword in React Native? I have a function with which the parent class itself is bound as 'this' but I want to access the properties of the element that is being clicked. Here's the code-
import {Circle} from 'react-native-svg';
export default App extends Component {
constructor(props) {
super(props);
this.state = {activeX: null}
}
handleTouch(event) {
const x = event.target.cx; //How to access "cx" property here?
this.setState({ activeX: x });
}
render() {
return (
<Circle cx='10' cy='10' r='5' onPress={this.handleTouch.bind(this)}/>
<Circle cx='20' cy='20' r='5' onPress={this.handleTouch.bind(this)}/>
);
}
}
Try this
import {Circle} from 'react-native-svg';
export default App extends Component {
constructor(props) {
super(props);
this.state = {
activeX: null,
cx: 10
}
}
handleTouch = () => {
const x = this.state.cx
this.setState({ activeX: x });
}
render() {
return (
<Circle cx={this.state.cx} cy='10' r='5' onPress={this.handleTouch}/>
);
}
}
import ReactNativeComponentTree from'react-native/Libraries/Renderer/src/renderers/native/ReactNativeComponentTree';
And access the properties as-
const x = ReactNativeComponentTree.getInstanceFromNode(event.currentTarget)._currentElement.props.cx;
Sorry for leaving an answer but I cannot leave a comment since <50 rep.
You should edit the improve part of your answer, with the following bit:
import ReactNativeComponentTree from 'react-native';
instead of what you have right now,
import ReactNativeComponentTree from'react-native/Libraries/Renderer/src/renderers/native/ReactNativeComponentTree';
since is throwing an error (trying to import unknown module).
A better way of accessing the component properties in an event is actually by creating a component and passing it the needed data:
import { Circle } from 'react-native-svg';
class TouchableCircle extends React.PureComponent {
constructor(props) {
super(props);
this.circlePressed = this.circlePressed.bind(this);
}
circlePressed(){
this.props.onPress(this.props.cx);
}
render() {
return (
<Circle cx={this.props.cx} cy={this.props.cy} r={this.props.r} onPress={this.circlePressed}/>
);
}
}
export default App extends Component {
constructor(props) {
super(props);
this.state = {activeX: null}
this.handleTouch = this.handleTouch.bind(this);
}
handleTouch(cx) {
this.setState({ activeX: cx });
}
render() {
return (
<TouchableCircle cx='10' cy='10' r='5' onPress={this.handleTouch}/>
<TouchableCircle cx='20' cy='20' r='5' onPress={this.handleTouch}/>
);
}
}
NB: Performance tip from Facebook for event handlers:
We generally recommend binding in the constructor or using the property initializer syntax, to avoid this sort of performance problem. (i.e. to avoid the creation of the callback everytime a component renders)
ref: React Handling Events
(credits to https://stackoverflow.com/a/42125039/1152843)
You can change your event handler to a curried function like so:
import {Circle} from 'react-native-svg';
export default App extends Component {
constructor(props) {
super(props);
this.state = {activeX: null}
}
//Use ES6 arrow and avoid this.bind
//Curried function handleTouch accepts cx, cy as extra parameters
handleTouch = (cx, cy) => event => {
console.log(cx, cy) // This is how you access props passed to Circle here
console.log(event)
this.setState({ activeX: cx });
}
render() {
//You are actually invoking the handleTouch function here, whose return value is
//a function, which is set as the onPress event handler for the <Circle> component
return (
<Circle cx='10' cy='10' r='5' onPress={this.handleTouch(10, 10)}/>
<Circle cx='20' cy='20' r='5' onPress={this.handleTouch.(20, 20)}/>
);
}
}
Checkout the working snack below:
https://snack.expo.io/#prashand/accessing-props-from-react-native-touch-event

Headless Task use inside component with React Native

I am trying to run a background task using headlessjs in react-native. The problem is that I am unable to access the async task inside the component in order to show it on the view. Here's my default component.
import React, { Component } from 'react';
import {
AppRegistry,
Text,
View,
NativeModules
} from 'react-native';
module.exports = NativeModules.ToastAndroid;
someTask = require('./SomeTaskName.js');
export default class test2 extends Component {
constructor() {
super()
this.state = {
myText: 'My Original Text'
}
}
updateText = () => {
this.setState({myText: 'My Changed Text'});s
}
componentDidMount(){
this.setState({myText: someTask});
someTask.then(function(e){ //<--- error
console.log("lala" + e);
});
}
render() {
return (
<View>
<Text>
abc
</Text>
</View>
);
}
}
AppRegistry.registerComponent('test2', () => test2);
AppRegistry.registerHeadlessTask('SomeTaskName', () => someTask);
As mentioned in the code, I get the error undefined is not a function. I don't know how to make this work. My SomeTaskName.js looks like this.
SomeTaskName.js
module.exports = async (taskData) => {
return taskData.myname;
}
The idea is to simply get the data from the service and show it on the UI.
The solution was to simply move the code inside the componentDidMount function. Here's how I achieved it.
/**
* Sample React Native App
* https://github.com/facebook/react-native
* #flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
Text,
View,
Image
} from 'react-native';
export default class test2 extends Component {
constructor() {
super()
this.state = {
myText: '1'
}
}
componentWillUnmount() {
}
componentDidMount(){
someTask = async (taskData) => {
this.setState({ myText: taskData.myname});
}
};
}
render() {
return (<Text>Working</Text>);
}
}
AppRegistry.registerHeadlessTask('SomeTaskName', () => someTask);
AppRegistry.registerComponent('test2', () => test2);
You can replace :
someTask = require('./SomeTaskName.js');
by
import SomeTaskName from './SomeTaskName'

React Native Router Flux: passing params between scenes

I have a list of items (jobs) and when an item (job) is being selected, a new scene is being opened. I want the ID of the selected item to be passed from the scene with the list to the other scene with the details about the selected item (job) without using Redux.
Router
import React from 'react';
import { Scene, Router } from 'react-native-router-flux';
import JobsList from './components/JobsList';
import Job from './components/Job';
const RouterComponent = () => {
return (
<Router>
<Scene key="jobs" component={JobsList} initial />
<Scene key="Job" component={Job} title="Test" />
</Router>
);
};
export default RouterComponent;
Jobs list
import React, { Component } from 'react';
export default class JobsList extends Component {
render() {
return (
<TouchableOpacity onPress={() => { Actions.Job({ jobId: jobId }) }}>
...
</TouchableOpacity>
);
}
}
Job
import React, { Component } from 'react';
export default class Job extends Component {
constructor() {
super();
this.state = {
job: {}
};
axios.get(
// PROBLEM: this.props.jobId is empty
`http://api.tidyme.dev:5000/${this.props.jobId}.json`,
{
headers: { Authorization: 'Token token=123' }
}
).then(response => this.setState({
job: response.data
}));
}
render() {
return (
<Text>{this.state.job.customer.firstName}</Text>
);
}
}
You should call super(props) if you want to access this.props inside the constructor.
constructor(props) {
super(props);
console.log(this.props);
}
The best practice is defining Components as pure functions:
const Job = ({ job, JobId}) => {
return (
<Text>{job.customer.firstName}</Text>
);
}
otherFunctions() {
...
}

React-Native error this.setState is not a function

I'm using below lib to implement a callback (onSuccess, onError) for every ApiRequest. But I have a problem when update state when event is trigged. I tried to remove all stuffs just keep the base logic. I don't know why it error.
Lib: https://www.npmjs.com/package/react-native-simple-events
Below is my code
ApiRequest.js
import Events from 'react-native-simple-events';
export function login(email, password) {
Events.trigger('LoginSuccess', 'response');
}
Login.js
import React, { Component, } from 'react'
import {
View,
Text,
} from 'react-native'
import Events from 'react-native-simple-events';
import * as request from '../../network/ApiRequest'
class LoginScreen extends Component {
static propTypes = {}
static defaultProps = {}
constructor(props) {
super(props)
this.state = {
status: "new"
}
}
componentDidMount() {
Events.on('LoginSuccess', 'myID', this.onLoginSuccess);
request.login("abc","def")
}
componentWillUnmount() {
Events.rm('LoginSuccess', 'myID');
}
onLoginSuccess(data){
this.setState({ //=>error here
status : "done"
});
}
render() {
return (
<View>
<Text>
{this.state.status}
</Text>
</View>
)
}
}
let me know if you need more information
You need to bind this on the onLoginSuccess method:
Events.on('LoginSuccess', 'myID', this.onLoginSuccess.bind(this));