Undefined is not a function: Timers - React Native - timer

I am trying to make an app where the SplashScreen is shown for 600 milliseconds and then the Mainscreen is displayed. I used the setTimeOut method in componentDidmount, but I am getting the error as shown here. The necessary code is also provided below.
import React, { Component } from 'react';
import {Image,Dimensions, Button, Text, StyleSheet, View, TouchableOpacity} from 'react-native';
var timePassed;
class SplashScreen extends Component{
constructor(props){
super(props);
this.state={
timePassed: false
}
}
componentDidMount() {
this.setTimeout( () => {
this.setState({timePassed: true})
},600);
}
render(){
if(!this.state.timePassed){
return(
<View style={styles.container}>
<Image style={styles.logo} source={require('./Images/logo.jpg')} resizeMode="contain" />
<Text style={styles.deadlineFont}>Deadline</Text>
</View>
);
}
else{
return (
<View>
<MainScreen />
</View>
);
}
}
}

Problem: setTimeout is wrongly called with this but is not a method defined on your class.
Solution: Change this.setTimeout( () => { to setTimeout( () => {.
Here's a working example of your code: https://repl.it/Iqfk/1

Related

state value (on Test2.js) not changing in react-native for the given below code

First thing is that in Test1.js when i uses Test2.js two time.In the first one I passes the data="First" and in second one I passes data="Second". But when the screen render and when I press the Button First It show "First" on the screen but when I press button second,it do'nt render "Second" on screen.
As I found that the value of state in the Test2.js is not changing.
Can You explain me why the value of state is not changing in the Test2.js
And can anyone tell how to fix this.And more thing if I uses component instead of this.A() and this.B() it works fine but as below method not works.
Here is the code..
Test1.js
import React, { Component } from 'react'
import { Text, StyleSheet, View } from 'react-native'
import {Button} from 'react-native-elements'
import Test2 from './Test2';
var a = "First"
var b = "second"
export default class Test1 extends Component {
state={
activeA:true,
activeB:false
}
A = ()=>{
return( <Test2 data={a}/>)
}
B = () =>{
return(<Test2 data={b}/>)
}
render() {
return (
<View style={{ flex:1,justifyContent:'center',padding:20}}>
<Button buttonStyle={{ marginBottom: 10}} title="First" onPress={()=>{this.setState({activeA:true,activeB:false})}}/>
<Button buttonStyle={{ marginBottom: 10}} title="Second" onPress={()=>{this.setState({activeA:false,activeB:true,})}}/>
{this.state.activeA?this.A():this.B()}
</View>
)
}
}
Test2.js
import React, { Component } from 'react'
import { Text, View } from 'react-native'
export default class Test2 extends Component {
state={
data:this.props.data
}
render() {
return (
<View>
<Text syle = {{fontSize:20,}}> {this.state.data} </Text>
</View>
)
}
}
Do not transfer to the status value, but render directly.
Test2.js
import React, { Component } from 'react'
import { Text, View } from 'react-native'
export default class Test2 extends Component {
constructor(props) {
super(props);
const { data } = props
}
render() {
return (
<View>
<Text syle = {{fontSize:20,}}> {this.props.data} </Text>
</View>
)
}
}
Test2.propTypes = {
data: PropTypes.string
}

React-Native the child component don't render the information within the parent component

I'm developing a React Native app that using a ScrollView. I want to display an amount of items (A card with title and a child component).
The problem comes when I have to render each item, while the parent renders ok, the child does not.
I don't know where could be the issue, here's my code:
import React, {Component} from 'react';
import {View, Text} from 'react-native';
const mismo =[
'Mismo',
'Mismo',
'Mismo',
'Mismo',
'Mismo'
];
class Mismo extends Component {
renderMismo2(){
mismo.map((item) =>{
return(
<View>
<Text>{item}</Text>
</View>
)
})
}
render(){
return(
<View>
{this.renderMismo2()}
</View>
);
}
}
export default Mismo;
=================================
import React, {Component} from 'react';
import {View, Text, ScrollView} from 'react-native';
import {Card} from 'react-native-elements';
import PriceCard from '../components/PriceCard';
import Mismo from '../components/Mismo';
class OrderPricingCard extends Component{
renderAllPrices(){
this.props.data.orders.map((item, i) => {
return(
<View>
<PriceCard
key={item.transporterName}
data={item}
/>
</View>
);
})
}
renderMismo(){
return(
<Mismo />
);
}
render () {
return (
<Card
containerStyle={styles.cardContainer}
title={`Pedido: ${this.props.data.id}`}
>
<ScrollView
horizontal
>
{this.renderMismo()}
{this.renderAllPrices()}
</ScrollView>
</Card>
);
}
}
const styles = {
cardContainer:{
borderRadius: 10,
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
}
}
export default OrderPricingCard;
This can be an easy mistake to make! I've done it several times. What's happened is you've forgotten the return statement for the render methods (renderMismo2() and renderAllPrices()) found in each component. Although the map methods correctly have return statements, you're not actually returning anything from the functions themselves.
If you were to console.log() either of those function calls above the return in the React render() method, you would see undefined in the console.
Here's what they would look like corrected.
renderAllPrices(){
// added the 'return' keyword to begin the line below
return this.props.data.orders.map((item, i) => {
return(
<View>
<PriceCard
key={item.transporterName}
data={item}
/>
</View>
);
})
}
renderMismo2(){
// same here, added the 'return' keyword
return mismo.map((item) =>{
return(
<View>
<Text>{item}</Text>
</View>
)
})
}
I tested the above in a React Native sandbox and it works. Hope that helps!

undefined is not a function (evaluating 'RNViewShot.captureRef(view,options)')

I am trying to save a view in android by react native.In Expo while taking viewshot, the React native viewshot throws the below error in android. This is my code
import React from 'react';
import { View ,Image,Button} from 'react-native';
import ViewShot from "react-native-view-shot"
import { captureRef } from "react-native-view-shot";
export default class App extends React.Component {
constructor(props){
super(props)
this.capture = this.capture.bind(this)
}
capture(){
this.refs.viewShot.capture().then(uri => {
console.log("do something with ", uri);
},(error)=>{console.log("error",error)})
}
render() {
return (
<View style={styles.container}>
<ViewShot ref="viewShot" >
<Image source={require("./batman.jpg")}>
</Image>
</ViewShot>
<Button
title="save"
onPress={this.capture}
>
</Button>
</View>
);
}
}

Reloading an animation React-native-animatable library

guy's I'm using the react-native-animatable library. Basically, when I load my app the animation runs, however, when I go to another tab and return to the initial page the animation doesn't run anymore. I think it's because it' doesn't get reloaded anymore and I was wondering how to reload a component. As you can see the View has an animation prop which is the animation which has to be loaded.
import React, { Component } from 'react';
import { Text, Button, StyleSheet, Image, ImageBackground, TouchableOpacity } from 'react-native';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import LinearGradient from 'react-native-linear-gradient';
import {Fonts} from '../components/Fonts';
import { createAnimatableComponent, View, } from 'react-native-animatable';
class Home extends React.Component {
render() {
return (
<View style={styles.container}>
<View animation='bounceInLeft'
style={styles.container1}>
<View style={styles.card1}>
<ImageBackground
source={require('../images/pictures/runop.jpg')}
style={{width:'100%', height:200, }}>
<Text
style={{fontSize:30, alignSelf:'center', color:'white',
fontFamily:Fonts.Nunito}}
> Sport Schema's</Text>
</ImageBackground>
</View>
</View>
<View animation='bounceInRight' style={styles.container2}>
<View style={styles.card2}>
<Image
source={require('../images/pictures/foodop.jpg')}
style={{width:'100%', height:200}}/>
</View>
</View>
<View animation='bounceInLeft' style={styles.container3}>
<View style={styles.card3}>
<Image
source={require('../images/pictures/blogop.jpg')}
style={{width:'100%', height:200}}/>
</View>
</View>
</View>
);
}
}
Thanks for your help. I eventually got it to work with a different method.
I used the withNavigationFocus from react-navigation to get the isFocused props of the current screen. Then i just used an if statement if screen is focused then run animation else dont.
import {withNavigationFocus} from 'react-navigation';
class Profile extends React.Component {
constructor(props) {
super(props);
}
render()
// This checks if current screen is focused then run the animation otherwise dont.
{
if (this.props.isFocused && this.animation) {
this.animation.bounce(800)
}
return (
<View ref={(ref) => {this.animation = ref;}}
style={styles.container3}>
<View style={styles.card3}>
<Text> hii</Text>
</View>
</View>
);
}
}
});
export default withNavigationFocus(Profile); // <- dont forget this!!
If you are using react-navigation, below solution might work for you.
Create a function which would start the animation after some milliseconds and pass it to the next screen as params. Example,
SCREEN A
animateFunction() {
setTimeout(() => {
// start your animation
}, 100);
}
navigation.navigate(SCREEN_NAME, { startPrevScreenAnimation: animateFunction });
And in the next screen call that function when the component unmounts (componentWillUnmount()). Example,
SCREEN B
componentWillUnmount() {
this.props.navigation.state.params.startPrevScreenAnimation();
}
I said some milliseconds because you would want the animation to start once the screen transition is complete.
OR
Add a listener to your screen which fires an event when the screen is in focus.
if (this.props.navigation) {
this.willFocusSubscription = this.props.navigation.addListener(
'willFocus',
() => { // Run your animation },
);
}

React Native : undefined is not an object

I am currently learning React Native.
I just a built a very simple app to test out the Button component.
When I click on the button component the console log is printed as expected.
But after printing out the console log it pops out the following error.
**undefined is not an object (evaluating '_this2.btnPress().bind')**
I am not sure what is wrong ?
Can anyone let me know what I am doing wrong ?
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
export default class App extends React.Component {
btnPress() {
console.log("Fn Button pressed");
}
render() {
return (
<View style={styles.container}>
<Button title="this is a test"
onPress={()=> this.btnPress().bind(this)} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
You are invoking the function instead of passing a reference through bind.
loose the ().
And you should not wrap it with an arrow function as bind is already returning a new function instance
onPress={this.btnPress.bind(this)} />
By the way, this will return and create a function instance on each render, you should do it once in the constructor (which runs only once):
export default class App extends React.Component {
constructor(props){
super(props);
this.btnPress = this.btnPress.bind(this);
}
btnPress() {
console.log("Fn Button pressed");
}
render() {
return (
<View style={styles.container}>
<Button title="this is a test"
onPress={this.btnPress} />
</View>
);
}
}
Or use an arrow function which uses a lexical context for this:
export default class App extends React.Component {
btnPress = () => {
console.log("Fn Button pressed");
}
render() {
return (
<View style={styles.container}>
<Button title="this is a test"
onPress={this.btnPress} />
</View>
);
}
}

Resources