I am new to react native. What I want to achieve is that I want to navigate between screen while using pressable. What i have done is I have already created pressable button components inside buttons.js file what I want right now is that when I call that component inside of a file I want to pass screen name as a prop to that button component and navigate between screen using that main component. In short what i mean is whenever a screen name is passed from different file it act according to that and instead I don`t have to create multiple navigation inside each file.
E.g
Inside Home file
<ButtonXsPrimary
title='Login'
/>
Inside Buttons.js file
const ButtonXsPrimary = (prop) => {
const navigation = useNavigation();
return (
<>
<Pressable style={[style.buttonXs, Color.bgSecondry]} onPress={() => navigation.navigate(prop)} >
<Text style={[Color.White, style.buttonsTextSm]}>{prop.title}</Text>
</Pressable>
</>
);
};
The same title prop is used for navigation
As I understand you can do this way,
You need to pass navigation and route name as a prop inside your ButtonXsPrimary like
<ButtonXsPrimary
title="Login"
navigation={navigation}
routeName={'YourRouteName'}
/>
Access the props
onPress={() => prop.navigation.navigate(prop.routeName)}
I'm currently developing an app using react native and I'm using react-navigation to navigate between screens, using buttons in my header (back arrow for example).
It's working well, however even if my icon is the right size it seems like the click area is really narrow and I struggle with it.
Do you know how I could define a click zone on my button for it to be clicked easier? I've tried the hitslop prop but it's not working for me (maybe it's been deprecated?).
Here is my button:
var backArrow =
<TouchableOpacity onPress={() => this.props.navigation.goBack()}>
<Ionicons name="ios-arrow-back" size={22} color="#ff8c00" />
</TouchableOpacity>
I'm using Expo and testing on an iPhone 6s Plus.
Wrapping the Ionicons in a TouchableOpacity will only provide a clickable area as large as the Ionicons component. You can increase the size of the clickable area with the following structure:
<TouchableOpacity>
<View>
<Ionicons />
</View>
</TouchableOpacity>
by styling the View to be as large as you require it.
I'm trying to create a dynamic drawer in react-native-router-flux.
I Mean when I changed the Scenes drawer can detect which scene in now activated and can update itself by new data.
I have a Component in my drawer that calls in App.js
<Drawer
key={'drawer'}
contentComponent = {() => <DrawerLayout language={this.state.language} />}
drawerPosition= {this.state.rightOrLeft}
<Stack key={'root'} hideNavBar>
<Scene key={'splash'} component={Splash} initial/>
<Scene key={'login'} component={Login} />
<Scene key={'home'} component={Home} />
<Scene key={'about'} component={About} />
</Stack>
</Drawer>
I wish I could explain my dream correctly !!!
If you are using redux you can retain state and fetch the current scene from store and play around with it.
If you are not using redux, you can still get to do it without it. One option is to do the following:
use contentComponent in DrawerNavigator and fetch the content from a separate js file.
contentComponent: props => <SideBar {...props} />
Now you need global variable declare in App.js name as currentScene and set your home page as default.
Now lets join all in sideBar.js, on click of every menu item change the global variable value to the selected menu.
Based on the value of current scene in SideBar.js change menuItems List.
One good example is react native base kitchen sink example app. Read the code in it follow the four steps once you are familiarise with it and you will be done.
https://github.com/GeekyAnts/NativeBase-KitchenSink
I want to add a burger menu button when viewing certain pages and a right side button that appears on all pages. Is this possible with react-native-router-flux?
UPDATE: I was able to get the right side button in without too much trouble by using this code
<Scene key="home"
component={HomePage}
hideBackImage={true}
...
rightButtonImage={HelpIcon}
onRight={()=>{}}
rightTitle={null}
rightButtonIconStyle={{ width: 44, height: 44 }} />
The burger menu button is proving more difficult. There is a drawerImage property on the Navigation Bar, but no other documentation about how to make that drawerImage appear and how to set a handler function.
I tried setting the rightButtonImage, onRight rightTitle and rightButtonIconStyle the same way I did for the left button but no button appeared.
UPDATE 2: I downgraded to react-native-router-flux v3.34.0 because of this issue: https://github.com/aksonov/react-native-router-flux/issues/1154
and added these props to my scene:
...
renderBackButton={()=>{ return null; }} /* Hide the back button...goofy mechanism but it works */
leftButtonImage={NavigationBurgerIcon}
onLeft={()=>{}}
leftTitle={null}
leftButtonIconStyle={{ width: 30, height: 30 }}
...
You can write your own Navigation bar for 100% control. You can structure your NavBar component off of their implementation of NavBar and do the following:
<Router
navBar={NavBar}
...
/>
The react-native-router-flux api has more details on this.
Once done you can create custom properties to add to your scene that drive various NavBar behavior custom to your project such as how you want to interact with the hamburger icon.
You could do something like this.
<Router renderLeftButton={this.navBarButton}>
<Scene .....
</Router>
function:
navBarButton(){
return(
<TouchableOpacity onPress={() => Actions.refresh({ key: 'drawer', open: true })}>
<Icon name='ios-menu' size={30} />
</TouchableOpacity>
)
}
Using react-native-vector-icons
I'm new to React Native, so am probably asking something very obvious, but please help.
I have a view wrapped in a touchable, so that the whole area responds to tapping. Then have a ScrollView nested inside the view. The overall structure is something like this:
<TouchableWithoutFeedback onPress={this.handlePress.bind(this)}>
<View>
<ScrollView>
<Text>Hello, here is a very long text that needs scrolling.</Text>
<ScrollView>
</View>
</TouchableWithoutFeedback>
When this compiles and runs, the tapping is detected, but the scroll view doesn't scroll at all. I made the above code short and simple, but each component has the proper styling and I can see everything rendering fine and the long text is cutoff at the bottom of the ScrollView. Please help.
Thank you!
This is what worked for me:
<TouchableWithoutFeedback onPress={...}>
<View>
<ScrollView>
<View onStartShouldSetResponder={() => true}>
// Scrollable content
</View>
</ScrollView>
</View>
</TouchableWithoutFeedback>
The onStartShouldSetResponder prop stops the touch event propagation towards the TouchableWithoutFeedback element.
I'm using this structure it's working for me:
<TouchableWithoutFeedback onPress={() => {}}>
{other content}
<View onStartShouldSetResponder={() => true}>
<ScrollView>
{scrollable content}
</ScrollView>
</View>
</TouchableWithoutFeedback>
You can have a scrollView or FlatList inside a TouchableWithoutFeedback. Tho you shouldn't but some times you have no other choice to go. Taking a good look at this questions and answer validates that.
close react native modal by clicking on overlay,
how to dismiss modal by tapping screen in react native.
For the Question, The only way you can make it work (atleast that i know of), or the simplest way is to add a TouchableOpacity around Text in your code like this,
<TouchableWithoutFeedback onPress={this.handlePress.bind(this)}>
<View>
<ScrollView>
<TouchableOpacity>
<Text>Hello, here is a very long text that needs scrolling.</Text>
</TouchableOpacity>
<ScrollView>
</View>
</TouchableWithoutFeedback>
Note: TouchableOpacity is a wrapper for making Views respond properly to touches so automatically you can style it the way you would have styled your View Component then set some of its special props to whatever you want e.g activeOpacity etc. Moreso you can use TouchableHighlight it works, but it receives one child element i.e you enclose all your component inside a parent one.
I'm using this structure it's working for me:
<TouchableOpacity>
{other content}
<ScrollView>
<TouchableOpacity activeOpacity={1}>
{scrollable content}
</TouchableOpacity>
</ScrollView>
I found that for my situation the other examples did not work as they disabled the ability to click or disabled the ability to scroll. I instead used:
<FlatList
data={[{key: text1 }, { key: text2 } ...]}
renderItem={({ item }) => (
<TouchableWithoutFeedback onPress={this.onPressContent}>
<Text style={styles.text}>{item.key}</Text>
</TouchableWithoutFeedback>
)}
/>
I happend to need to multiple chunks but you could use single element in the data array for one piece of text.
This let the press event to fire as well as let the text scroll.
Trying to use a ScrollView component inside a TouchableWithoutFeedback component can cause some unexpected behavior because the TouchableWithoutFeedback component is designed to capture user gestures and trigger an action, but the ScrollView component is designed to allow users to scroll through content.Here is what the official docs say
Do not use unless you have a very good reason. All elements that
respond to press should have a visual feedback when touched.
TouchableWithoutFeedback supports only one child. If you wish to have
several child components, wrap them in a View. Importantly,
TouchableWithoutFeedback works by cloning its child and applying
responder props to it. It is therefore required that any intermediary
components pass through those props to the underlying React Native
component.
Thats write , you cannot have a scroll view inside the TouchableWithoutFeedback, it the property of react native that it will disable it, you can instead have your scroll view outside the TouchableWithoutFeedback tab and add the other contents that you want upon the click inside a view tag.
You can also use the Touchable Highlights instead, if the TouchableWithoutFeedback does not works.