How to pass Screen Name to another component - reactjs

I have a common Header component. How can I pass 'Screen Name' to this component?
I want to pass the 'Screen Name' from Home to HeaderStyle.
I want to use the headerstyle in other component and pass 'Screen Name' to the headerstyle
import HeaderStyle From './HeaderStyle '
export default class Home extends Component {
render (){
return (
// <HeaderStyle>Screen Name</HeaderStyle>
<HeaderStyle Name={"Screen Name"}/>
<HeaderStyle />
)
}
export default class HeaderStyle extends Component {
render() {
return (
<View>
<Header >
<View style={{
width: width, height: hp('12%'),
flexDirection: 'row', backgroundColor: '#141414'
}} >
<Left>
<Image style={styles.logo}
source={require('../assets/images/1x/logo.png')}>
</Image>
</Left>
<View style={{ marginLeft: 280, marginTop: 20 }}>
<Text style={{ color: 'white', fontSize: 35, fontWeight: 'bold' }}>
Should be Dynamic Screen Name</Text></View>
<Right>
<TouchableOpacity onPress={this.ShowHideComponent2}>
<Image style={styles.imgsearch} source={require('../assets/test/a.png')}>
</Image>
</TouchableOpacity>
</Right>
</View>
</Header>
{this.showAssests()}
</View>
);
}
}

Create a function and read window.location.pathname , then in Header component render that function, for Example
export default function currentScreenName(){
let screenName = '';
switch(window.location.pathname){
case '/employees':
screenName = 'Employees';
break;
case '/admin':
screenName = 'Admin';
break;
default:
screenName = 'Dashboard';
}
return screenName;
}
//Header.js
<h1>{currentScreenName()}</h1>

You can simply pass the header prop in static navigationOptions directly inside the screen component.
For example
In your screen component
class HomeScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
header: <HeaderStyle Name={"Screen Name"}/>
};
/* render function, etc */
}
Inside HeaderStyle component use the props in the Text
<Text style={{ color: 'white', fontSize: 35, fontWeight: 'bold' }}>
{this.props.Name}
</Text>
Find more information on header customisation here

thanks a lot i solve the problem
in the home Screen i send the screen name like this
<Headerstyle title={"text"} />
and in the HeaderStyle i receive the title like this
<Text >{this.props.title}</Text>

Related

the style does not work on images (Image) how can I fix it?

the style does not work on images (Image); how can I fix it?
For example, style 2-card is applied without an image
but when I add images, the style changes, I don't understand why.
Icons are visible on Card-2, but after adding an image on card-1, the photo closes the icons
export default class Cards extends Component{
render(){
return(
<View style={{...styles.container, backgroundColor:this.props.bg }}>
<View style={styles.col}>
<Image
style={styles.col}
source={this.props.imageUri}
/>
<Icon
name={this.props.icon}
size={30}
color={this.props.bg == "red" ? "red":"red"}
/>
<TouchableOpacity onPress={this.props.onPress}>
<Icon2
style={{marginLeft:50}}
name="dots-vertical"
size={30}
color="red"
/>
</TouchableOpacity>
</View>
<Text style={styles.title}>{this.props.title}</Text>
<Text style={{
...styles.number,
color: this.props.bg == "red" ? "#FFF":"#000",
}}>
{this.props.number}
</Text>
</View>
)
}
}
const styles = StyleSheet.create({
container:{
height:200,
width:130,
borderRadius:30,
padding:15,
marginLeft:20
},
col: {
flexDirection:"row"
},
title:{
marginTop:90,
color:"#b8b8aa",
fontWeight:"bold",
fontSize:12
},
number:{
fontWeight:'bold',
fontSize:22
}
})
example
I have created a sample based on your code.
Basically overflow: 'hidden' of the container did the trick

Preventing state item in all components from changing with useContext()?

I'm trying to control the state of 2 components use useContext() in React-Native. I have a flatmap of cards that render on a screen. Each card has a press-able 'interested' icon. If I click on a card, it shows the details of the card and also the press-able 'interested' icon. Both should share the same state of being pressed and also send a 'interested bool to the backend.
Right now, if I press 'interested' on one card, the all get pressed. Same with the inside icon of the details page. Obviously the 'interested' state in the Context Provider is to broad and changing all of them. How can I filter out the state change?
Here is the card component that gets rendered from a flatlist:
import React, { useState, useEffect, useContext } from 'react';
import { Image, View, Text, TouchableOpacity } from 'react-native';
import { localDate } from 'utils/formatDate';
import PropTypes from 'prop-types';
import { ConcertContext } from '../../../context/ConcertContextProvider';
import LocationIcon from '../../../assets/images/locationIcon.svg';
import InterestedFilledIcon from '../../../assets/images/interested-filled.svg';
import InterestedEmptyIcon from '../../../assets/images/interested-empty.svg';
import ShareIcon from '../../../assets/images/share.svg';
import styles from './styles';
export default function ConcertCard({
gotoConcertPage,
artist,
cover,
concertCity,
scheduledAt,
description,
concertObj,
}) {
const [clickInterest, setClickInterest] = useState(concertObj.is_interested);
const { interested, setInterested, concertInterest } = useContext(ConcertContext);
const handleInterest = () => {
setInterested(prevState => !prevState);
concertInterest(concertObj);
};
useEffect(() => {
setClickInterest(interested);
}, [interested]);
return (
<TouchableOpacity onPress={() => gotoConcertPage(concertObj)}>
<View style={styles.card}>
<View style={styles.cardContent}>
<View style={styles.cropped}>
<Image style={styles.image} source={{ url: cover.url }} />
</View>
<View style={styles.textWrapper}>
<Text style={styles.date}>{localDate(scheduledAt, 'MMM D, h:mm A z')}</Text>
<View style={styles.locationWrapper}>
<LocationIcon style={styles.locationIcon} />
<Text style={styles.location}>{concertCity.name}</Text>
<Text style={styles.location}>{concertCity.address}</Text>
</View>
<Text style={styles.name}>{artist.name}</Text>
<Text style={styles.description}>{description}</Text>
</View>
<View style={styles.border} />
</View>
<View style={styles.icons}>
<View style={styles.sharedIcon}>
<ShareIcon />
</View>
{!clickInterest ? (
<InterestedEmptyIcon onPress={handleInterest} />
) : (
<InterestedFilledIcon onPress={handleInterest} />
)}
</View>
</View>
</TouchableOpacity>
);
}
ConcertCard.propTypes = {
gotoConcertPage: PropTypes.func,
artist: PropTypes.object,
cover: PropTypes.object,
concertCity: PropTypes.object,
scheduledAt: PropTypes.string,
description: PropTypes.string,
concertObj: PropTypes.object,
};
Here is the card details page:
import React, { useState, useEffect, useContext } from 'react';
import { Text, View, Image, ImageBackground, ScrollView, FlatList } from 'react-native';
import PropTypes from 'prop-types';
import Button from 'components/button';
import { localDate } from 'utils/formatDate';
import { ConcertContext } from '../../context/ConcertContextProvider';
import LocationIcon from '../../assets/images/locationIconTwo.svg';
import LittleFriendIcon from '../../assets/images/little-friend.svg';
import Star from '../../assets/images/Star.svg';
import QuestionMarkIcon from '../../assets/images/question-mark.svg';
import ShareIcon from '../../assets/images/ShareIconLarge.svg';
import styles from './concertStyles';
export default function ConcertPageScreen({ navigation, route }) {
const {
concertObj,
name,
artist,
scheduled_at,
interests,
concert_city,
other_cities,
description,
ticket_base_price,
} = route.params;
const { interested, setInterested, concertInterest } = useContext(ConcertContext);
const formatLocation = city => {
return city.slice(0, city.length - 5);
};
const handleInterest = () => {
setInterested(prevState => !prevState);
concertInterest(concertObj);
};
const buyTicket = concertObj => {
console.log('Buy ticked: ', concertObj.id);
};
return (
<>
<View style={styles.wrapper}>
<ImageBackground
style={styles.imageBackground}
imageStyle={{ opacity: 0.3 }}
source={{ url: artist.media }}
/>
<ScrollView vertical>
<View style={styles.headerWrapper}>
<Text style={styles.headerTitle}>{name}</Text>
<Text style={styles.smallText}>{artist.name}</Text>
<Text style={styles.date}>{localDate(scheduled_at, 'MMM D, h:mm A z')}</Text>
<View style={styles.locationWrapper}>
<LocationIcon style={styles.locationIcon} />
<Text style={styles.location}>{concert_city.name}</Text>
<Text style={styles.location}>{concert_city.address}</Text>
</View>
<Text style={styles.description}>{description}</Text>
<View style={styles.interestedWrapper}>
<LittleFriendIcon style={styles.littleMan} />
<Text style={styles.interested}>{interests} Interested</Text>
</View>
<View
style={{
borderTopColor: '#DADADA',
borderTopWidth: 0.2,
borderStyle: 'solid',
alignSelf: 'center',
height: 5,
marginTop: 32,
marginBottom: 28.5,
}}
/>
<View style={styles.tableWrapper}>
<View style={styles.tableHeaderWrapper}>
<Text style={styles.headerTitle}>DATES</Text>
<Text style={styles.headerTitle}>LOCATIONS</Text>
</View>
<View>
<FlatList
data={other_cities}
initialNumToRender={1}
renderItem={({ item }) => (
<View style={styles.tableItemsWrapper}>
<Text style={styles.dateItem}>
{localDate(item.date, 'MMM DD - h:mm A z')}
</Text>
<Text style={styles.locationItem}>{formatLocation(item.city)}</Text>
</View>
)}
concertCityId={item => `item${item.concert_city_id}`}
concertScheduleId={item => `item${item.concert_schedule_id}`}
/>
</View>
</View>
<View style={styles.iconWrapper}>
<View style={{ backgroundColor: '#292929', width: 44, height: 44, borderRadius: 30 }}>
<ShareIcon style={styles.shareIcon} />
</View>
{!interested ? (
<View
style={{ backgroundColor: '#292929', width: 44, height: 44, borderRadius: 30 }}>
<Star style={styles.starIcon} onPress={handleInterest} />
</View>
) : (
<View
style={{ backgroundColor: '#007AFF', width: 44, height: 44, borderRadius: 30 }}>
<Star style={styles.starIcon} onPress={handleInterest} />
</View>
)}
<Image style={styles.roundAvatar} source={{ url: artist.media }} />
</View>
<View style={styles.iconWrapper}>
<Text style={styles.shareIconText}>Share</Text>
<Text style={styles.interestedIconText}>I'm Interested</Text>
<Text style={styles.artistIconText}>Add Artist</Text>
</View>
<View style={styles.ticketWrapper}>
<Text style={styles.ticketPrice}>TICKET PRICES</Text>
<QuestionMarkIcon style={styles.ticketPrice} />
</View>
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
<Text style={styles.ticketLocation}>In-location</Text>
<Text style={styles.ticketLocation}>$ {ticket_base_price}</Text>
</View>
<View
style={{
borderTopColor: '#DADADA',
borderTopWidth: 0.5,
borderStyle: 'solid',
height: 20,
marginTop: 32,
marginBottom: 28.5,
}}
/>
<View style={styles.footerWrapper}>
<Text style={styles.headerTitle}>TICKET GUIDE</Text>
<Text style={styles.ticketDescription}>
This ticket is for a livestream concert. Sign In at www.colortv.me on your browser
to watch on our TV or laptop. On the go? Watch from the COLOR TV mobile app.
</Text>
</View>
</View>
<Button
rightIcon={false}
text="Buy Ticket"
style={styles.button}
onPress={() => buyTicket(concertObj)}
/>
</ScrollView>
</View>
</>
);
}
ConcertPageScreen.propTypes = {
navigation: PropTypes.object,
route: PropTypes.object,
};
and here is the Context Provider:
import React, { createContext, useState } from 'react';
import { concertInterestApi } from 'utils/apiRoutes';
import useFetcher from 'hooks/useFetcher';
import parseError from '../utils/parseError';
export const ConcertContext = createContext(null);
const ConcertContextProvider = ({ children }) => {
const { isLoading, error, fetcher } = useFetcher();
const [interested, setInterested] = useState([]);
const concertInterest = async concertObj => {
try {
await fetcher({
url: concertInterestApi(concertObj.id),
method: concertObj.is_interested ? 'DELETE' : 'POST',
});
} catch ({ response }) {
throw parseError(response);
}
};
return (
<ConcertContext.Provider value={{ interested, setInterested, concertInterest }}>
{children}
</ConcertContext.Provider>
);
};
export default ConcertContextProvider;
Perhaps I'm not wiring this up correctly at all and any suggestions would be welcome to manage state.
You are confused about the shape of your own context. In your Provider, interested is an array (I'm not sure of what) and setInterested is a function to replace that array. With that in mind, hopefully you can see the problem with this:
const { interested, setInterested, concertInterest } = useContext(ConcertContext);
const handleInterest = () => {
setInterested(prevState => !prevState);
concertInterest(concertObj);
};
You are treating interested as a boolean when it is an array. I think it's all of the concerts that this user is interested it? Or perhaps an array of all userIds who are interested in this concert? Or perhaps useState([]) is a mistake and it was always meant to be a boolean?
Either way, I would recommend moving the shared logic from the ConcertCard and ConcertPageScreen into a custom hook that consumes your context and return an onClickInterested handler function. Your hook can take the concert id and/or user id as an argument.

Detect active screen in React Native

Sorry for my bad English. I have built a navigation bar without using Tab Navigation from React Navigation, everything works fine except when I try to set an 'active' icon, I have handled it with states but the state restarts when I navigate to another window and render the bar again navigation.
I think I have complicated it a bit, but I need to capture the active screen to pass it as status and change the color of the icon to 'active' and the others disabled. I have tried with Detect active screen and onDidFocus but I only received information about the transition, I require the name or id of the screen.
I leave my code (this component is exported to each page where I wish to have the navigation bar). Please, the idea is to not use Tab Navigation from React Native Navigation.
export default class Navbar extends Component {
/** Navigation functions by clicking on the icon (image) */
_onPressHome() {
this.props.navigation.navigate('Main');
}
_onPressSearch() {
this.props.navigation.navigate('Main');
}
render() {
const { height, width } = Dimensions.get('window');
return (
<View style={{ flexDirection: 'row', height: height * .1, justifyContent: 'space-between', padding: height * .02 }}>
/** Icon section go Home screen */
<View style={{ height: height * .06, alignItems: 'center' }}>
<TouchableOpacity
onPress={() => this._onPressHome()}
style={styles.iconStyle}>
<Image
source={HOME_ICON}
style={{ width: height * .04, height: height * .04, }} />
<Text style={[styles.footerText, { color: this.state.colorA }]}>Inicio</Text>
</TouchableOpacity>
</View>
/** Icon section go Search screen */
<View style={{ height: height * .06, alignItems: 'center' }} >
<TouchableOpacity
onPress={() => this._onPressSearch()}
style={styles.iconStyle}>
<Image
source={SEARCH_ICON}
style={{ width: height * .04, height: height * .04, opacity: .6 }} />
<Text style={[styles.footerText, { color: this.state.colorB }]}>Inicio</Text>
</TouchableOpacity>
</View>
</View>
)
}
}
For the navigation I used createStackNavigator and also
const drawerNavigatorConfig = {
contentComponent: props => <CustomDrawerContentComponent {...props}
/>,
};
const AppDrawer = createDrawerNavigator(drawerRouteConfig,
drawerNavigatorConfig);
I do not know if createDrawerNavigator is interfering with something, I read that it generates additional keys. Please help me with this.
import { useIsFocused } from '#react-navigation/native';
function Profile() {
const isFocused = useIsFocused();
return <Text>{isFocused ? 'focused' : 'unfocused'}</Text>;
}
check documentation
https://reactnavigation.org/docs/use-is-focused/
You can use this inViewPort library for checking the view port of the user. This is how you can user the library
render(){
<InViewPort onChange={(isVisible) => this.checkVisible(isVisible)}>
<View style={{flex: 1, height: 200, backgroundColor: 'blue'}}>
<Text style={{color: 'white'}}>View is visible? {this.state.visible </Text>
</View>
</InViewPort>
}

React-Native + Redux passing ID to component

I am new to react-native and recently implemented Redux in my app.
The App is for ordering food in Restaurants :)
This is a snippet of my Restaurant-Details Screen with cards, which are representing the different menus:
<View style={{alignItems: 'center'}}>
{menus.map((item) => {
return (
<Card style={{width: '95%'}}>
<TouchableOpacity onPress ={() => this.props.navigation.navigate('Products', { menuId: item.sk_id } ,{bestellung})}>
<CardItem cardBody style={{justifyContent: 'center', alignItems: 'center'}}>
<Text style={styles.textdes}> {item.typ} </Text>
</CardItem>
</TouchableOpacity>
</Card>
)
})}
As you can see the onPress Function navigates to the Product Screen and passes a menuId! (Product Screen shows all the food of a specific menu)
This is my Product.js:
class Products extends Component {
constructor(props) {
super(props);
this.state = {
loading: 1
};
}
componentDidMount = () => {
this.props.fetchProducts();
this.state.menuId;
}
addItemsToCart = (product) => {
this.props.addToCart(product);
}
render() {
const { products, navigation } = this.props
const {params} = this.props.navigation.state;
const menuId = params ? params.menuId : null;
return (
<View style={styles.container}>
<Header style={styles.header}>
<Left>
<Button transparent onPress={() =>
this.props.navigation.goBack()}>
<Icon style={{ fontSize: 35, color: '#FFFFFF'}}
active name="arrow-back" />
</Button>
</Left>
<Body>
<Title style={{ fontSize: 25}}>{menuId}</Title>
</Body>
<Right style={{position: 'absolute', right: 20}}>
<Cart navigation={navigation}/>
</Right>
</Header>
<StatusBar barStyle="light-content" backgroundColor="#383838"
translucent={false} />
<View style={styles.bodyProducts}>
<View>
<Text style={{color:
'#000', fontSize: 50}}>{menuId}</Text>
</View>
<FlatList
data={products}
renderItem={({item}) =>
<Product item={item} addItemsToCart=
{this.addItemsToCart} product={item}/>}
keyExtractor ={(item) => item.id}
/>
</View>
</View>
);
}
}
const mapStateToProps = (state) => ({
products: state.products.items
})
export default connect(mapStateToProps {addToCart,fetchProducts})(Products);
The Product.js fetches products from my product.component.js:
class Product extends Component {
addToCart = () => {
this.props.addItemsToCart(this.props.item)
}
render() {
const { product, menuId } = this.props;
return (
<Card>
<View style={styles.container}>
<Image source={product.picture} style={{width:400,height:150}}/>
<View style={styles.productDes}>
<CardItem cardBody style={{justifyContent: 'center',
alignItems: 'center'}}>
<Text style={styles.font}>{menuId}</Text>
</CardItem>
<Text style={{fontSize: 20}}>€{(product.cost).toFixed(2)}
</Text>
<Text style={{fontSize: 16}}>{product.description}</Text>
<TouchableOpacity onPress={this.addToCart} style=
{styles.addBtn}>
<Text style={styles.text}>Hinzufügen</Text>
</TouchableOpacity>
</View>
</View>
</Card>
);
}
}
export default Product;
The question is now: How can I pass the menuId from product.js to
product.component.js without naviagtion?
I hope I could make clear, what my problem is and looking forward to your solutions and help :)
Maybe you should better separate your React components - which are basically views - and your reducers / side-effect (data fetching...) components.
State is in Redux Store, Views only display what's in store.
If you don't want to pass menuId through navigation params, you can add it to your store state - basically you add a field in your reducer's state to save the currently selected menuId.
In your Restaurant-Details screen, when calling onPress, you dispatch an action with the selectedMenuId to your redux store.
Then in your product screen, you retrieve the selectedMenuId from your redux store.
To understand Redux architecture , I like this gif:
Since you're already using Redux, why not store the menu ID you're currently viewing in your store? When the user selects a menu item, dispatch an action to set the current menu ID. Then use a selector to to get the menu ID in the component you need it.
I hope I haven't misunderstood your issue.

React Native move navigator text

Hey In react native I'm using and Everything works well so far but the title and the back button text don't line up. (The login is higher then register) Any ideas how I could set this up?
render() {
const titleConfig = {
title: 'login',
tintColor: "white",
}
return(
<View style={styles.bb}>
<NavigationBar
title={titleConfig}
tintColor="black" />
</View>
)
}
You can pass in a react element to title prop with styling to make it align as per your requirements. For e.g:
render() {
const title = <View style={styles.navTitle}>
<Text style={styles.navTitleText}>Login</Text>
</View>;
return (
<View style={styles.bb}>
<NavigationBar
title={title}
tintColor="black"
/>
</View>
);
}
var styles = StyleSheet.create({
navTitleText: {
color: "white",
fontSize: 19,
marginBottom: 4,
}
});
Here's the complete guide about the API https://github.com/react-native-fellowship/react-native-navbar#api

Resources