So im using the Pressable Component in react-native instead of using Button because i've heard it has many limitations regarding styling. I've tried using TouchableHighlight as well but it isnt working porperly for me moreso since my Component already has some styling and Positioning adjusted into it
class randomComponent extends Component {
render() {
return (
<Pressable>
<Text>Hello World</Text>
</Pressable>
)
}
tl:dr How do i Highlight a Pressable Component? thanks
You can just use the "render prop" style instead if you want access to the pressed state without having to store your own useState variable.
From the docs:
<Pressable
style={({ pressed }) => [
{
backgroundColor: pressed
? 'rgb(210, 230, 255)'
: 'white'
},
styles.wrapperCustom
]}>
{({ pressed }) => (
<Text style={styles.text}>
{pressed ? 'Pressed!' : 'Press Me'}
</Text>
)}
</Pressable>
Solution:
import { TouchableOpacity } from 'react-native'
TouchableOpacity is better for developers with experience in a web-based background and styling.
You need to use a state variable to store the pressed state and change the component style accordingly
class randomComponent extends Component {
constructor(props) {
super(props)
this.state = {
pressed: false
}
}
render() {
return (
<Pressable
onPressIn={() => this.setState({pressed: true})}
onPressOut={() => this.setState({pressed: false})}
style={this.state.pressed ? styles.pressed : {}}
>
<Text>Hello World</Text>
</Pressable>
)
}
const styles = StyleSheet.create({
pressed: {
backgroundColor: 'red'
}
})
Related
I am using TouchableOpacity from react-native. The code is:
<TouchableOpacity onPress={onPress}>
<Text style={styles.supplementItem}>{item.item}</Text>
</TouchableOpacity>
where the OnPress function is as:
const onPress = () => (
// eslint-disable-next-line no-sequences
<Text style={styles.supplementItem}>Hello</Text>
this.setState({tempKey: tempKey + 1})
);
I looked at: this question and tried to do like it. But this is not working. I am setting my states as follows:
constructor(props) {
super(props);
this.state = {
tempKey: 0,
};
}
Kindly help me what I am doing wrong.
The question which you mentioned is using function based components and you are using class based components as you showed the costructor part which proves that.
So onPress must be a method in that class in your case, so you don't need the const keyword before it and you need to call it in this way ; this.onPress
In nutshell, your whole component should be like this;
import React from 'react';
import {Text, TouchableOpacity, View} from 'react-native';
class YourComp extends React.Component {
constructor(props) {
super(props);
this.state = {
tempKey: 0,
show: false
};
}
onPress = () => {
// eslint-disable-next-line no-sequences
this.setState(prevState => ({tempKey: prevState.tempKey + 1}))
};
render() {
return (
<View>
<TouchableOpacity style={{height: 100, justifyContent: 'center', alignItems: 'center'}} onPress={() => this.onPress()}>
<Text>Hello (item.item in your case)</Text>
</TouchableOpacity>
<Text key={this.state.tempKey.toString()}>Hello {this.state.tempKey}</Text>
</View>
)
}
}
export default YourComp;
If you want to show some component conditionally;
this.state = {
...,
show: false
}
Then in the onPress method;
this.setState(prevState => ({show: !prevState.show})) // this will make <Text /> to toggle the modal when clicked.
Then in the render method;
<Text>
{this.state.show && (
<YourNewComponent />
) || null}
</Text>
<TouchableOpacity>
<Text style={styles1.picturebutton}>Picture</Text>
</TouchableOpacity>
When I click "Picture", I want to get a modal(popup). How can I do so?
Thank you so much
You can do with something like this:
import React, {Component} from 'react'
import { View, Modal, TouchableOpacity, Text} from 'react-native'
export default class ViewPager extends Component {
constructor(props: Props) {
super(props)
this.state = {
IsModalVisible: false
}
}
render() {
return (
<View>
<Modal visible={this.state.IsModalVisible} onRequestClose={() => this.setState({IsModalVisibl: false})}>
<View>
<Text style={{color: (IsDarkThemeActive[0] ? 'white' : 'black')}}>Your modal Here</Text>
</View>
</Modal>
<TouchableOpacity onPress={() => this.setState({IsModalVisible: true})}>
<Text style={styles1.picturebutton}>Picture</Text>
</TouchableOpacity>
</View>
)
}
}
A button who changes the state of the visibility of the modal
You should take a look at : https://reactnative.dev/docs/modal its not that hard to accomplish.
Basically you set a state like showModal and say it is false by default but when you click your button it turns true and if u click it again it toggles back.
Then you just have to conditinally tell react native where it should render the modal if showModal is set to true.
Gl Faded.
I am having an issue where my onPress of a touchable opacity doesn't fire. I am sure it isn't working because nothing console logs to the system when I press it.
My button component:
const FloatingPlusButton = (props) => {
return (
<View style={styles.buttonStyle}>
<TouchableOpacity onPress={props.tapToAddEvent}>
<MaterialIcons
name='add'
size={45}
color='#28313b'
/>
</TouchableOpacity>
</View>
);
};
Where I call it:
class HomeScreen extends Component {
constructor() {
super();
this.state = {
textInput: '',
inputVisible: true
};
}
onFloatingButtonPress() {
this.setState({ inputVisible: true }, () => { this.textInputField.focus(); });
console.log('p');
}
render() {
return (
<View style={{ flex: 1, height: HEIGHT }}>
{ !this.state.inputVisible &&
<FloatingPlusButton tapToAddEvent={this.onFloatingButtonPress.bind(this)} />
}
</View>
);
}
}
To be clear I do see the button and the inputVisible prop is not the issue. Just nothing happens when I press it. I tried it with both the .bind(this) and without it and neither worked.
I was able to figure it out. I had to make the zIndex of the button greater than the zIndex of the root view component. Thanks for the help everybody.
I have created a composed component to compose TouchableNativeFeedback to wrapperComponent.
export default function withFeedback2(
WrappedComponent
) {
return class extends BaseComponent {
constructor(props) {
super(props);
}
render() {
return (
<View>
<TouchableNativeFeedback
onPress={() => this.props.onContainerViewPress()}
>
<WrappedComponent {...this.props} />
</TouchableNativeFeedback>
{/* <TouchableOpacity
onPress={this.props.onContainerViewPress ? () => this.props.onContainerViewPress() : null}
>
<WrappedComponent {...this.props} />
</TouchableOpacity> */}
</View>
);
}
};
}
But OnPress event of TochableNativeFeedback is not firing. Whereas OnPress event is fired correctly and onContainerViewPress prop of wrappercomponent is called if wrappercomponent wrapped under TouchableOpacity.
I am testing this on the Android Platform.
Use a <View></View> to wrap your WrappedComponent for TouchableNativeFeedback.
<TouchableNativeFeedback
onPress={() => this.props.onContainerViewPress()}>
<View>
<WrappedComponent {...this.props} />
</View>
</TouchableNativeFeedback>
There are two different TouchableNativeFeedback classes. Make sure you import the correct one:
import { TouchableNativeFeedback } from "react-native"
import { TouchableNativeFeedback } from "react-native-gesture-handler"
I had a similar problem and finally used it from "react-native" library. Importing it from "react-native-gesture-handler" did not work for me.
I've discovered that adding a Ripple effect to the TouchableNativeFeedback fixes the issue for me:
background={TouchableNativeFeedback.Ripple("#FFFFFF",true)}
i.e.
export default function withFeedback2(
WrappedComponent
) {
return class extends BaseComponent {
constructor(props) {
super(props);
}
render() {
return (
<View>
<TouchableNativeFeedback
onPress={() => this.props.onContainerViewPress()}
background={TouchableNativeFeedback.Ripple("#FFFFFF",true)}
>
<WrappedComponent {...this.props} />
</TouchableNativeFeedback>
</View>
);
}
};
}
Try: useForeground={true}
<TouchableNativeFeedback onPress={() => {}} useForeground={true}>
You can call method as below:
export default function withFeedback2(
WrappedComponent
) {
return class extends BaseComponent {
constructor(props) {
super(props);
this.onContainerViewPress = this.onContainerViewPress.bind(this);
}
onContainerViewPress() {
const { onContainerViewPress } = this.props;
onContainerViewPress();
}
render() {
return (
<View>
<TouchableNativeFeedback
onPress={() => { this.onContainerViewPress(); }}
>
<WrappedComponent {...this.props} />
</TouchableNativeFeedback>
{/* <TouchableOpacity
onPress={this.props.onContainerViewPress ? () => this.props.onContainerViewPress() : null}
>
<WrappedComponent {...this.props} />
</TouchableOpacity> */}
</View>
);
}
};
}
Try to import Touchable native feedback from react native gesture handler library
import { TouchableNativeFeedback } from "react-native"
import { TouchableNativeFeedback } from "react-native-gesture-handler"
Supplementing the answer of mangei the problem could be if you import it from the wrong place. You have to import it from react-native-gesture-handler if you are inside a gesture handler (NOTE: react-navigation's TabBar itself has a PanGestureHandler in it by default). What react-native-gesture-handler does is it wraps components like ScrollView or TouchableNativeFeedback with its own implementation to be able to handle gestures inside the GestureHandler as well that are "not meant" for the GestureHandler but rather for the ScrollView or the TouchableNativeFeedback. If you're inside the gesture handler, you have to import it from react-native-gesture-handler else from react-native.
How can I add a view to the bottom of the screen with the click of a button, which is at the top of the screen, in React Native?
you make the view at the bottom of the screen conditionally render based on a state and you set it that state to be true on the OnPress method of the button
I think it is better to learn more about state and props and other fundamental concepts in react/react-native first:
https://facebook.github.io/react-vr/docs/components-props-and-state.html
but here is how you can do this:
You need to define a state if you can view that section as
false
, then when the button pressed, change the value of that state to
true
import React from 'react';
import {Text,View,TouchableOpacity} from 'react-native';
export default class testComponent extends React.Component {
constructor(){
super()
this.state = {
viewSection :false
}
}
renderBottomComponent(){
if(this.state.viewSection) {
return (
<View>
<Text>Hi!</Text>
</View>
)
}
}
buttonPress=()=>{
this.setState({viewSection:true})
}
render() {
return (
<View >
<TouchableOpacity onPress={this.buttonPress}>
<Text> Click Me!</Text>
</TouchableOpacity>
{this.renderBottomComponent()}
</View>
);
}
}
You can try this,
According to my knowledge this is what you want
import React, { useState } from 'react';
import { Button, View } from 'react-native';
export default function Testing() {
const Square = () => (
<View style={{
width: 50,
height: 50,
margin: 10,
backgroundColor: "green",
}} />
);
const [squares, setSquares] = useState([<Square />, <Square />, <Square />]);
return (
<View >
{squares.map(v => v)}
<Button title='add' onPress={() => setSquares([...squares, <Square />])} />
</View >
)
}