Changing Screen names in react native expo - react-native

I have the following 2 screens:
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="SubScreen1" component={SubScreen1} />
I would like to change the screen name of 'SubScreen1' to 'Search Result' but I am getting the error of The action 'NAVIGATE' with payload {"name":"SubScreen1","params":{"paramKey":"Japanese"}} was not handled by any navigator.
How come I am having this error as I have another screen which I just change the name and there is no error.
In my Home Screen:
<View style = {styles.container}>
<Text>Welcome {auth.currentUser?.email}</Text>
<Text></Text>
<Text>What cusine would you like to eat today?</Text>
<DropDownPicker
open={open}
value={value}
items={items}
setOpen={setOpen}
setValue={setValue}
setItems={setItems}
/>
<TouchableOpacity
onPress={() => navigation.navigate("SubScreen1", {paramKey:value})}
style = {styles.button}
>
<Text style = {styles.buttonText}>Search</Text>
</TouchableOpacity>
In my SubScreen1 screen
import { StyleSheet, Text, View } from 'react-native'
import React from 'react'
const SubScreen1 = ({route}) => {
const paramKey = route.params.paramKey
console.log(paramKey)
return (
<View>
<Text>{paramKey}</Text>
</View>
)
}
export default SubScreen1
const styles = StyleSheet.create({})

Not sure i understood your question properly but if you want to change the header text of your screen to "Search Result" then just add title property in the Stack.Screen options like below
<Stack.Screen
name="SubScreen1"
component={SubScreen1}
options={{ title: 'Search Result' }}
/>
https://reactnavigation.org/docs/headers/#setting-the-header-title

Related

passing text input between custom header using stack navigation

I wanted to connect the SearchMain, SearchHistoryList, and SearchResult screens using the custom header of the stack navigation.
At first, the SearchMain screen appeared,
and when the TextInput in the custom header is onFocus, the SearchHistory screen appeared,
and the SearchResult screen appeared when the TextInput is onSubmitEditing or when the SearchButton was pressed.
Also, I set the keyboard focus to be maintained when switching screens, and use Keyboard.discuss() when I want to close it.
However, if you enter something at the TextInput in custom header immediately after the screen changes, it will be entered at the TextInput on the previous screen.
I think it's because the three screens don't share a single custom header!! each header is created, and the keyboard focus on the previous screen!!
I want all screens use the same header, or the values of the headers are consistent.
What should I do to solve this problem?
I searched variously such as singleton header, static header, and header value consistent, but there is no good solution.
I recently started studying React Native, so I'm not sure about my method, and a completely different approach is also welcome~~
Below is my code, thanks.
const Stack = createStackNavigator();
function NavigationBar({navigation}){
const [query, setQuery] = React.useState('');
function changeSearchQuery(text : string) : void {
setQuery(text);
}
function deleteSearchQuery() : void {
setQuery("");
}
return(
<InputView>
<BackIcon onPress={() => {navigation.goBack()
Keyboard.dismiss()}}>
<Icon name="arrow-back-ios" size={widthPercentage(24)} color="#666666"/>
</BackIcon>
<InputText
keyboardType="default"
maxLength={100}
onChangeText={(str) => setQuery(str)}
value = {query}
placeholder="검색어 입력"
placeholderTextColor="#E9E9E9"
returnKeyType="search"
onFocus={() => navigation.navigate("SearchHistory", {changeSearchQuery:changeSearchQuery})}
onSubmitEditing={() => {navigation.navigate("SearchResult", {changeSearchQuery:changeSearchQuery})
Keyboard.dismiss()}}
allowFontScaling= {false}
/>
{ query.length > 0 &&
<DeleteIcon onPress={() => deleteSearchQuery()}>
<Icon name="clear" size={widthPercentage(20)} color="#666666"/>
</DeleteIcon>
}
<SearchIcon onPress={() => {navigation.navigate("SearchResult")
Keyboard.dismiss()}}>
<Icon name="search" size={widthPercentage(20)} color="#666666"/>
</SearchIcon>
<Line></Line>
</InputView>
);
}
export const Search = () =>{
return (
<Stack.Navigator initialRouteName="SearchMain" keyboardHandlingEnabled={false} screenOptions={{header:props => <NavigationBar navigation={props.navigation}/>}}>
<Stack.Screen name="SearchMain" component={SearchMain} options={{animationEnabled: false}}/>
<Stack.Screen name="SearchHistory" component={SearchHistory} options={{animationEnabled: false}}/>
<Stack.Screen name="SearchResult" component={SearchResult} options={{animationEnabled: false}}/>
<Stack.Screen name="SearchFilter" component={SearchFilter} options={{headerShown: false}}/>
</Stack.Navigator>
);
}
export default Search;
It's not a good pattern to set the state inside the header, instead you should centralized the state in your component and then use navigation.setOption to pass functions/state value.
In this way your header will look like this:
function NavigationBar({
query,
onFocus,
onChangeText,
onPressBackIcon,
onSubmitEditing,
onDeleteSearch,
onSearch
}){
return(
<InputView>
<BackIcon onPress={onPressBackIcon}>
<Icon name="arrow-back-ios" size={widthPercentage(24)} color="#666666"/>
</BackIcon>
<InputText
keyboardType="default"
maxLength={100}
onChangeText={onChangeText}
value = {query}
placeholder="검색어 입력"
placeholderTextColor="#E9E9E9"
returnKeyType="search"
onFocus={onFocus}
onSubmitEditing={onSubmitEditing}
allowFontScaling= {false}
/>
{ query.length > 0 &&
<DeleteIcon onPress={onDeleteSearch}>
<Icon name="clear" size={widthPercentage(20)} color="#666666"/>
</DeleteIcon>
}
<SearchIcon onPress={onSearch}>
<Icon name="search" size={widthPercentage(20)} color="#666666"/>
</SearchIcon>
<Line></Line>
</InputView>
);
}
Than you will have in SearchMainScreen your state, your functions and your custom header:
// remember headerMode='none' in screen option
const SearchMainScreen = () => {
const [query, setQuery] = React.useState('');
const onFocus = () => {}
...
return (
<View>
<NavigationBar
onFocus={onFocus}
query={query}
...
/>
{
(isFocus && !query) ?
<SearchHistoryComponent/> :
(isFocus && query) ?
<SearchResultComponent/> :
<List/>
}
</View>
)
}

Adding background color to app.js on react-native

I want to add a default color for all my screens on react-native. My entry file doesn't have a default react-native component that takes in styles as prop. Hence, I'll be asking "How to add styles when Navigation container is present". I have tried adding the cardStyle prop on Drawer.Screen but it doesn't work.
Here's a sample of my code
<NavigationContainer>
<Drawer.Navigator>
<Drawer.Screen name='SignUp' component={SignUp} />
<Drawer.Screen name='Reset Password' component={ResetPassword}/>
<Drawer.Screen name="Forgot Password" component={ForgotPasswordScreen} />
<Drawer.Screen name='Login' component={Login} />
<Drawer.Screen name="Verify Email" component={EmailVerification} />
</Drawer.Navigator>
</NavigationContainer>
Simply we have to create a Root Component in which we can put the background color.
For Example.
Create a Root Component with background color:
const RootComponent = props => {
return (
<View style={{ flex: 1, backgroundColor: "YOUR_BACKGROUND_COLOR" }} >
{props.children}
</View>
)
}
export default RootComponent;
Now we can import the Root Component in our screens in which screens we are supposed to show the same background color.
for Example:
const HomeScreen = props => {
return (
<RootComponent>
{
/* YOUR HOME SCREEN COMPONENTS... */
}
</RootComponent>
)
}

Facing issue when trying to add image on bottom tab navigation in react-native

When i am trying to adding image in bottom tab navigation then i just got only title of bottom tab.
How i can get image in bottom tab navigation in react-native?
I am using
import { NavigationContainer } from "#react-navigation/native"
import { createStackNavigator } from "#react-navigation/stack"
import { createBottomTabNavigator } from "#react-navigation/bottom-tabs"
//this libraries for achieve bottom tab navigation in react native.
function TabNav() {
return (
<Tab.Navigator
initialRouteName="Logbook"
tabBarOptions={{
activeTintColor: "#3498db",
}}
>
<Tab.Screen
name="Logbook"
component={Logbook}
options={{
tabBarLabel: 'Logbook',
tabBarIcon:({focused})=>{
focused?
<Image source={Images.logbookImg} style={styles.activeImg} />
: <Image source={Images.logbookImg} style={styles.deActiveImg} />
}
}}
/>
<Tab.Screen
name="Voyage"
component={Voyage}
options={{
tabBarLabel: 'Voyage',
tabBarIcon:({focused})=>{
focused?
<Image source={Images.voyageImg} style={styles.activeImg} />
: <Image source={Images.voyageImg} style={styles.deActiveImg} />
}
}}
/>
<Tab.Screen
component={Crew}
name="Crew"
options={{
tabBarLabel: 'Crew',
tabBarIcon:({focused})=>{
focused?
<Image source={Images.crewImg} style={styles.activeImg} />
: <Image source={Images.crewImg} style={styles.deActiveImg} />
}
}}
/>
</Tab.Navigator>
)
The problem is very simple, you are not returning the image
tabBarIcon:({focused})=>(
focused?
<Image source={Images.logbookImg} style={styles.activeImg} />
: <Image source={Images.logbookImg} style={styles.deActiveImg} />
)
replace the curly braces with brackets or put a return statement and it would work as expected.

React Native StackNavigator: Passing props from a screen to the header of the next screen

I have a React Native StackNavigator like so:
const AppStack = () => {
return (
<NavigationContainer theme={{ colors: { background: "white" }}}>
<Stack.Navigator headerMode="screen">
<Stack.Screen name="Master" component={ Master } />
<Stack.Screen
name="Details"
component={ Details }
options={{ headerTitle: props => <Header {...props} /> }} // <-- how can I pass props from Master to the Header here
/>
</Stack.Navigator>
</NavigationContainer>
)
}
The navigation works fine. When I'm on Master, if I press a TouchableOpacity, it brings up Details, with the header component Header.
However, what I want is to pass props from Master to the Header component in Details.
Something like this:
{/* What I want is that onPress, I want to pass someones_name and someones_photo_url to
the Details' Header component */ }
const Master = () => {
const someones_name = "Steve";
const someones_photo_url = "http://somephoto.com/001.jpg";
return (
<TouchableOpacity onPress={() => navigation.navigate("Details")}>
<Text>{ someones_name }</Text>
<Image source={{ uri: someones_photo_url }}>
</TouchableOpacity>
)
}
Is this possible?
You can pass values to other screens when navigating by doing the following:
Assume I am on screen "Feed" and click on someones name thus I want to go to screen "Profile" where it will show that user name that I clicked on.
In screen Feed
props.navigation.navigate('Profile, { userName: 'Shane' })`
In screen Profile I can grab that value passed in via navigate with:
const { userName } = props.route.params
To set this up inside a header assuming your screen options are outside the screen component and cannot access the props. Look into using setOptions to configure your header title dynamically.
props.navigation.setOptions({
headerTitle: ...
})

React Native: Sidebar is shown but unable to interact with it

I am using React Native Sidebar
This is the sidebar:
<Sidebar
ref={(ref) => this._drawer = ref}
leftSidebar={ this.renderLeftSidebar() }
leftSidebarWidth = {200}
>
</Sidebar>
This is how I'm rendering the left sidebar:
renderLeftSidebar = () =>{
return (
<View style = {{ position:'absolute', backgroundColor:'#24292e4f', height:Dimensions.get('window').height}}>
<DrawerContent/>
</View>
)
}
And this is the content for that left sidebar:
export default DrawerContent = () => {
return (
<View style={styles.animatedBox}>
<Image
source={require('../assets/images/header.png')}
style={{height:200, alignSelf:'center'}}
/>
<View style = {styles.drawerContentView}>
<Icon
name='setting'
type='antdesign'
color='#4abce3'
size ={22}
iconStyle = {styles.drawerItemIconStyle}
onPress={() => console.log('hello settings')}
/>
</View>
The sidebar opens just fine and renders correctly, but when I try and press anything on the sidebar the press goes through the sidebar and interacts with elements rendered beneath it. Should I be using zIndex in my styles or is my approach completely wrong?
If you are using React-native-vector-icons, the ICON itself has no button properties.
You can use Icon.Button
import Icon from 'react-native-vector-icons/AntDesign';
...
<Icon.Button
name='setting'
color='#4abce3'
size ={22}
iconStyle = {styles.drawerItemIconStyle}
onPress={() => console.log('hello settings')}
>
This is Setting
</Icon.Button>
OR You can use TouchableOpacity
import {
TouchableOpacity
} from 'react-native'
import Icon from 'react-native-vector-icons/AntDesign';
...
<TouchableOpacity onPress={() => console.log('hello settings')}>
<Icon
name='setting'
color='#4abce3'
size ={22}
iconStyle = {styles.drawerItemIconStyle}
/>
</TouchableOpacity>