I'm still doing my first steps in react native development for Android & iOS and I stumbled across a (supposedly simple) problem with buttons. I do not know how to modify a text field by pressing a button.
I tried using states, so this is how it currently looks like:
import React, { Component } from 'react';
import {
...
Button
} from 'react-native';
// more code
class ExampleButton extends ParseComponent {
constructor() {
super();
this.state = {
label: 'nothing'
}
}
// more code
render() {
if(...) {
return (
<Button
onPress={onButtonPress}
title="Click_test"
color="#841584"/>
);
}
}
const onButtonPress = () => { this.setState({label: 'something' });
However, I get an error message on pressing the button that says
... unexpected token, expected (....
in line const onButtonPress......
I'd be very about any hint! :) Thank you.
class ExampleButton extends ParseComponent {
constructor() {
super();
this.state = {
label: 'nothing'
}
}
// more code
onButtonPress = () => { //Make a property of ExampleButton class
this.setState({label: 'something' });
} //was missing this closing bracket
render() {
if(...) {
return (
<Button
onPress={this.onButtonPress} //change to this.onButtonPress
title="Click_test"
color="#841584"/>
);
}
}
Related
I get a problem to handle hardware back button android in React Native, I want to back in specific page/component when I press back button in hardware/device, but I always get error 'undefined is not an object (Evaluating 'this.props.navigation').
this is my script :
import { Platform, StyleSheet, Text, View, BackHandler } from 'react-native';
import { createStackNavigator, createAppContainer, NavigationActions, createBottomTabNavigator } from 'react-navigation';
import OnBoarding from './apps/src/onBoarding/OnBoarding';
import Welcome from './apps/src/welcome/Welcome';
import Login from './apps/src/login/Login';
const MainNavigator = createStackNavigator({
OnBoarding: OnBoarding,
Welcome: Welcome,
Login: Login
},{
initialRouteName: 'OnBoarding',
headerMode: 'none',
navigationOptions: {
headerVisible: false
}
});
const Approot = createAppContainer(MainNavigator);
var screen = '';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
routeName: ''
}
}
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
}
handleBackButton() {
if(screen == 'Login') {
this.props.navigation.navigate('OnBoarding');
}else{
return false;
}
}
getActiveRouteName(navigationState) {
if (!navigationState) {
return null;
}
const route = navigationState.routes[navigationState.index];
// dive into nested navigators
if (route.routes) {
return this.getActiveRouteName(route);
}
return route.routeName;
}
render() {
return <Approot onNavigationStateChange={(prevState, currentState) => {
screen = this.getActiveRouteName(currentState)
}} />;
}
}
in this case, I have 3 component, they are OnBoarding, Welcome, Login, when postion in Login I want to back to OnBoarding when press hardware back button, please help me to solve this problem.
Thanks.
You will have to use the navigation services as you want to navigate from outside of navigation (root of the app). you can follow documentation.
https://reactnavigation.org/docs/en/navigating-without-navigation-prop.html
I am rewriting a tutorial to TypeScript.
It should console.log after componentDidMount, but it doesn't. It doesn't show any error either.
What am I doing wrong?
Here's my code (minimized it for you):
import React from 'react';
import { View, Text, Animated, Keyboard } from 'react-native';
export class Logo extends React.PureComponent {
constructor(props) {
super(props);
}
componentDidMount() {
console.log(`Hey, I am mounted!`);
this.keyboardDidShowListener = Keyboard.addListener(
`Keyboard will show`,
this.keyboardWillShow
);
this.keyboardDidHideListener = Keyboard.addListener(
`Keyboard will hide`,
this.keyboardWillHide
);
}
componentWillUnmount() {
this.keyboardDidShowListener.remove();
this.keyboardDidHideListener.remove();
}
keyboardWillShow = () => {
console.log(`Keyboard shows`);
};
keyboardWillHide = () => {
console.log(`Keyboard hides`);
};
render() {
return (
<View>
<Text>
Type the amount right here
</Text>
</View>
);
}
}
Please help.
Tutorial code here: https://github.com/HandlebarLabs/currency-converter-starter/blob/module-3-lesson-10-animation/app/components/Logo/Logo.js
You can import EmitterSubscription interface, which is the return type for Keyboard.addListener(...) from react-native.
Looks like this:
import { Keyboard, EmitterSubscription } from 'react-native';
And then you can add this to your code:
...
export class Logo extends React.PureComponent {
constructor(props) {
super(props);
}
keyboardDidShowListener!: EmitterSubscription;
keyboardDidHideListener!: EmitterSubscription;
...
Note that I added an ! after the property to tell TypeScript that I make sure it gets a value assigned, in this case, in the componentDidMount()
Hope this helps!
I am currently transitioning from Wix RNN V1 to V2, and so far I've managed to find the appropriate replacement APIs, except for overriding the back button on Android.
In V1 we could pass the overrideBackPress: true attribute, and then handle back button presses manually on the cooresponding screen.
However, in V2 I've found no such replacement, and the only topics I could find were this thread:
https://github.com/wix/react-native-navigation/issues/4217
I've implemented the suggestions there, but Wix navigation is still automatically closing screens even though it should be overwritten.
Any known a solution for this?
I had the same issue and the only way i could override the backpress behavior on both platforms is to replace the left back button with custom button and use the BackHandler of react native for the hardware button in Android. The code is as below.
Component A
//Navigate to component B from A
Navigation.push(this.props.componentId, {
component: {
name: 'ComponentB',
options: {
topBar: {
leftButtons: [{
id: 'backPress',
text: 'Back',
icon: require('backbutton.png')
}]
},
}
}
});
Component B
import React, { PureComponent } from 'react';
import { View, BackHandler } from 'react-native';
import { Navigation } from 'react-native-navigation';
export default class ComponentB extends PureComponent {
constructor(props) {
super(props);
Navigation.events().bindComponent(this);
}
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress);
}
navigationButtonPressed({ buttonId }) {
switch (buttonId) {
case 'backPress': {
this.handleBackPress();
break;
}
}
}
handleBackPress = () => {
//Custom logic
//Go back if required
Navigation.pop(this.props.componentId)
//Stop the default navigation
return true;
};
//Render component
render() {
return (<View></View>);
}
}
You can use registerScreenPoppedListener:
Navigation.events().registerScreenPoppedListener((event) => {
if (event.componentId === "my-screen-id") {
// do something
}
});
i am using React Native Share Method (https://facebook.github.io/react-native/docs/share.html) to share content on Android.
As per documentation, we can use it in following ways:
Share.share({
message: 'React Native | A framework for building native apps using React'
})
.then((result) => {
console.log(result.action) // returns sharedAction
})
.catch((error) => {
console.log(error)
})
So when we call Share method, we will get result in then and popup window is appeared which contains apps list with which we can share the message content.
Issue:
Popup window also contains a cancel button, so when user click on it, window get closed, but there is no method available/mentioned to capture it, in docs.
Is there any way to capture the cancel event, as i want to perform some action when user clicks on it.
Thanks in adv. :)
There is option in share dismissedAction but unfortunately this is IOS only . You can use react-native-share with prop "failOnCancel" to true and it will work on both android and ios
Sample Code
import React, { Component } from "react";
import { Button } from "react-native";
import Share from "react-native-share";
export default class ShareExample extends Component {
onShare = async () => {
const shareOptions = {
title: "Share file",
social: Share.Social.EMAIL,
failOnCancel: true
};
try {
const ShareResponse = await Share.open(shareOptions);
//setResult(JSON.stringify(ShareResponse, null, 2));
} catch (error) {
console.log("Error =>", error);
}
};
render() {
return <Button onPress={this.onShare} title="Share" />;
}
}
App Preview
This might help
import React, {Component} from 'react';
import {Share, Button} from 'react-native';
class ShareExample extends Component {
onShare = async () => {
try {
const result = await Share.share({
message:
'React Native | A framework for building native apps using React',
});
if (result.action === Share.sharedAction) {
if (result.activityType) {
// shared with activity type of result.activityType
} else {
// shared
}
} else if (result.action === Share.dismissedAction) {
// dismissed
}
} catch (error) {
alert(error.message);
}
};
render() {
return <Button onPress={this.onShare} title="Share" />;
}
}
I am a newbie to React Native and was playing with Navigator when I hit this issue.
This is my main class in File A:
class SweetSpotClient_Proto extends Component {
render() {
return (
<Navigator
initialRoute={{ test: CategoryScene }}
renderScene={this.renderScene.bind(this)}/>
);
}
renderScene(route, navigator) {
return <CategoryScene test={route.test}/>
}
}
And this is my Scene in File B:
export default class CategoryScene extends Component {
render() {
...
var testArr = {... } ;
testArr.forEach(function(testEl) {
var test = this.props.test;
});
}
}
For some reason, in CategoryScene, this.props is null so I cannot access to this.props.test.
Am I doing something wrong?
I think it needs to be sent using passProps.
For example,
return <CategoryScene test={route.passProps}/>
check out Navigating like a Pro
It helped me a lot in my project.