I have two views in my react native app. and im using reactnavigtion to go to second view. below is that code.
<TouchableHighlight onPress={() => navigate('Detail', { title: 'Text' })}>
<View style={styles.box} >
</View>
</TouchableHighlight>
and above code works fine. in second view i added link to open up in the web browser when user tap on it.
<TouchableHighlight onPress={this._onPressButton('http://www.someurl.com')}>
<View style={styles.box} >
</View>
</TouchableHighlight>
and following is the method.
_onPressButton(url){
const uri = url;
Linking.openURL(uri).catch(err => console.error('An error occurred', err));
}
Problem is when i click to goto second view. it automatically fires the second view _onPressButton function as well. this happening in both iOS and Android.
The syntax you're using will invoke that function on every render which is why it's firing immediately. You have to either put it into an anonymous function or create a method for it.
<TouchableHighlight onPress={() => this._onPressButton('http://www.someurl.com')}>
or define a method that uses that argument
<TouchableHighlight onPress={this.navigateToSomeURL}>
Related
I am new to react JS, I am trying to display a QR code on button press, but the QR code does not show. This class is of the QR code
class HelloWorld extends Component {
state = {
text: 'http://facebook.github.io/react-native/',
};
render() {
return (
<View style={styles.container}>
<TextInput
style={styles.input}
onChangeText={(text) => this.setState({text: text})}
value={this.state.text}
/>
<QRCode
value={this.state.text}
size={1000}
bgColor='black'
fgColor='white'/>
</View>
);
};
}
const qr=new HelloWorld;
then I have created an object of hello world and called it in the profile, when a button is pressed.
> const qr=new HelloWorld;
const Profile = ({ navigation }) => {
return (
<View style={styles.container}>
<Text style={styles.title}>Vaccines</Text>
<TouchableHighlight onPress={() => qr.render()} underlayColor="white">
<View style={styles.button}>
<Text style={styles.buttonText}>SinoVac</Text>
</View>
</TouchableHighlight>
</View>
);
}
In the output, the profile is displayed but when I press the button nothing appears, neither do I get any error.
This is an interesting method of rendering a class component. Theoretically, it might work, but since I've never seen it before, I'm not shocked that it doesn't. It might do something if you write const qr = new HelloWorld(); before calling the render method (note the parens at the end, which are missing in your code). Even so, I would expect it to not behave as you want; you're calling render() within the onPress prop of a Touchable, which doesn't tell React where on the page to put it.
Even if it works somehow, I encourage you to use the standard method. Classes are usually rendered as any other JSX is: <HelloWorld />. Not only is this less code (you don't have to instantiate your class in a variable before calling its render method), it will be easier for others to read, and use the React model.
One common method of showing and hiding components is to keep a state value that controls whether they are shown. Your HelloWorld component is fine as written. I would change your Profile component to be something like the following:
const Profile = () => {
const [showQr, setShowQr] = useState(false);
return (
<View style={styles.container}>
<Text style={styles.title}>Vaccines</Text>
<TouchableHighlight onPress={() => setShowQr(!showQr)} underlayColor="white">
<View style={styles.button}>
<Text style={styles.buttonText}>SinoVac</Text>
</View>
</TouchableHighlight>
{showQr && <HelloWorld />}
</View>
);
}
I don't know where you want the QR to render, but using this code, it will show up after the button. There's a new piece of local state, showQr, which the button now toggles between true and false. When showQr is true, the HelloWorld component will be rendered.
I want to prevent user to copy content in TextInput but it works only on iOS but not for Android. How can I do this on Android?
[Update]: As the link #patel-dhara has given below, I already read commit about contextMenuHidden property and found that only handle onLongClick event on Android. So, still can copy to clipboard on TextInput by double-tap to it.
Here is my code:
<TextInput
style={styles.input}
placeholder="Password"
placeholderTextColor="rgba(255, 255, 255, 0.7)"
underlineColorAndroid="transparent"
secureTextEntry={isHidePass}
returnKeyType="go"
autoCapitalize="none"
onChangeText={this.handleTextChange}
onSubmitEditing={this.handleLogin}
ref={this.passwordRef}
contextMenuHidden
onBlur={() => Clipboard.setString('')}
onFocus={() => Clipboard.setString('')}
onSelectionChange={() => Clipboard.setString('')}
/>
you can use contextMenuHidden property of TextInput. It will work on both Platform Android and iOS.
<TextInput contextMenuHidden={true} />
but, It may be supported after react-native version 0.55. for more info link.
commit link for that: link
Try this:
<TextInput caretHidden={true} selectTextOnFocus={false} />
use this:
<View pointerEvents="none">
<TextInput ... />
</View>
Checkout pointer events for view:
https://facebook.github.io/react-native/docs/view#pointerevents
Another Option:
Try clearing the clipboard
<TextInput onFocus={() => Clipboard.setString('')} onSelectionChange={() => Clipboard.setString('')}/>
I you want to avoid pasting below solution works for me. I am clearing keyboard on onTouchEnd event
const [text1, setText1] = useState('')
const clearClipboard = () =>{
Clipboard.setString('')
}
const onChangeText = (text) =>{
//For android 12+ clipboard autofill option, dont allow text change more than one char..which means user is typing.
if(text1.length+1 >= text.length){
setText1(text)
}
}
<TextInput onChangeText={onChangeText} value={text1} contextMenuHidden={true} onTouchEnd={clearClipboard}></TextInput>
Hi I'm new in react native and I'm working on a sample chat app.Currently I'm facing a basic problem of navigation. Any help is appreciated.
I need to navigate from chat list to chat screen on click. Im using android emulator using Android studio. For this I wrote the script. But Im getting error when I click on a right_arrow having onPress function defined in the following code,
onContactPress = (item) =>{
Alert.alert();
}
renderFlatListItem({item}) {
return (
<View style={styles.container}>
<TouchableOpacity onPress={() => this.onContactPress(item)} >
<Image style={styles.rightArrow}
source={require('../../images/right_arrow.png')}/>
</TouchableOpacity>
</View>
)
}
and the the error is
undefined is not an object (evaluating '_this3.onContactPress()')
What I'm doing wrong here? Is there a way to pass the contact details of the selected person to the next screen? Please help me out.
This is in a React Class o functional component ?
In case of the 2nd call simply onContactPress without this, if your case is the first maybe you have a babel issue.
ok try this solution
change your onContactPress
from
onContactPress = (item) =>{
Alert.alert();
}
to
onContactPress({item}) {
Alert.alert();
}
because fat arrow functions should be defined outside the class
You probably have solved the issue by now. I'm new to React-Native myself and I came across your question after facing the same issue and I realized that the answer was in front of me all along.
Error Prone Script
I have a component with a state that contains an array of names created using the constructor method.
Ideally, when rendered this is the layout I was expecting on my Android device A list of User names and from there since I have assigned a key attribute and the value of the name's array index, when a user name is clicked I wanted to console.log(i), (i) being the index provided as a argument to the getValue() function in the onPress={} event listener.
But instead this is what I was getting the TypeError: undefined is not an object (evaluating 'this.getValues') error.
I tried reading docs, I googled, I looked at previously working codes, I did everything and nothing worked.
Nothing worked until I changed my renderName method from this
getValues(i){
console.log(i);
}
renderName(){
return this.state.names.map(function(name,i){
return (
<View>
<TouchableHighlight
key={i}
style={styles.viewName}
onPress={() => this.getValues(i)}>
<Text style={styles.name}>{name}</Text>
</TouchableHighlight>
</View>
)
})
}
To this
getValues(i){
console.log(i);
}
renderName(){
return this.state.names.map((name,i) => {
return (
<View>
<TouchableHighlight
key={i}
style={styles.viewName}
onPress={() => this.getValues(i)}>
<Text style={styles.name}>{name}</Text>
</TouchableHighlight>
</View>
)
})
}
The only difference is that I used a fat arrow function this.state.names.map((name,i) => { instead of the normal one this.state.names.map(function(name,i){
After making that change the results are what I was expecting Clicking a user name output the index associated with the name in the array
This may not solve your problem but I'll state it anyway through the following points
I caused my problem by trying to be too familiar with a Library I've basically just started learning.
Not every new error should make us panic, that's when we start asking bunch of questions rather than being calm enough to realize that the cause of the error is in front of us.
Experimenting with code is a good thing while you are learning but make sure that the code works as the tutorial instructs and that you fully understand it before you start making changes and playing around with it.
According to me you might be using Functional Component and in functional component you can call methods directly without using this. Just add const keyword outside the method and call without this keyword.
OnPress takes a function, instead, you're sending an encapsulated function.
Try this
onContactPress = (item) =>{
Alert.alert();
}
renderFlatListItem({item}) {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.onContactPress(item)} >
<Image style={styles.rightArrow}
source={require('../../images/right_arrow.png')}/>
</TouchableOpacity>
</View>
)
}
I am trying to navigate my first page to the second page by tapping a button.
Once we are at the second page, we will never go back by pressing back button.
Just tap, switch, and never go back.
Is there any simple way to do this?
I mean, I just don't want to use the component Navigation or Navigator. They are too complex.
I'm using React Navigation from guide of Facebook.
You can read more about this library from:
https://facebook.github.io/react-native/docs/navigation.html
Or react navigation's website:
https://reactnavigation.org/docs/intro/
Use this library to avoid the navigator. This is awesome
https://github.com/aksonov/react-native-router-flux
Once your scene keys are defined, you can navigate to them simply by calling Actions.keyname() on any screen
I don't know how complex your app is, but if it's really simple you can do it this way:
const setScreen = (screen) => {
setState({screen: screen})
}
render() {
<View>
{
switch(this.state.screen) {
case 'firstScreen': (
<View>
<Text>First Screen</Text>
<TouchableHighlight onPress={this.setScreen('secondScreen')}>
<Text>Go to second screen</Text>
</TouchableHighlight>
</View>
)
case 'secondScreen': (
<View>
<Text>Second Screen</Text>
<TouchableHighlight onPress={this.setScreen('firstScreen')}>
<Text>Go to first screen</Text>
</TouchableHighlight>
</View>
)
}
}
</View>
}
This mainly happens when we try to install a new package in our project and it does not get installed properly. I resolved this by
Delete android/app/build/intermediates/signing_config/debug/out/signing-config.json file.
Run yarn in the project root path.
I am trying to implement the solution proposed here for setting the focus on the next TextInput. The solution is proposed for iOS but I think it should also work for Android.
However I am getting the following exception:
undefined is not a function (evaluating '_this3.refs.Second.focus()')
I am using this Floating Label as my Text Input component. Here is my code:
<FloatingLabel
label='First'
ref='First'
validationRegex={/[A-Za-z0-9 ]+/}
value={this.props.First}
style={commonStyles.formInput}
onSubmitEditing={(event) => {this.refs.Second.focus()}}
onChangeText={(text) => this.onUpdate('First', text)}>
First</FloatingLabel>
<FloatingLabel
label='Second'
ref='Second'
style={commonStyles.formInput}
value={this.props.Second}
validationRegex={/(^([a-zA-Z]{5})([0-9]{4})([a-zA-Z]{1})$)/}
onChangeText={(text) => this.onUpdate('Second', text)}>
Second</FloatingLabel>
Can somebody help me in solving the exception? (RN 0.29, Android)
onSubmitEditing={(event) => {console.log(this.refs.Second)}} //works fine
Why am I unable to call the focus method?
this.refs.Second is a FloatingLabel object which don't have a method named "focus".
You can add a focus function to FloatingLabel component like below:
focus() {
this.refs.textInput.focus();
},
and add a ref to the TextInput in render
<View style={elementStyles}>
{this._renderLabel()}
<TextInput
ref={'textInput'}
{...props}
>
</TextInput>
</View>