tab navigation in react native is not working - javascript

import React from 'react'
import { View, Text, StyleSheet, TouchableWithoutFeedback } from "react-native";
const Header = props => {
const {
navigationState,
navigation,
activeTintColor,
inactiveTintColor
} = props;
const activeTabIndex = navigation.state.index;
return (
<View style={styles.containerHeader}>
<View style={styles.textContainer}>
<Text style={styles.textWhite}>Win Bets</Text>
<Text style={styles.textWhiteSmall}>win cash daily</Text>
</View>
<View style={styles.tabContainer}>
{navigationState.routes.map((route, index) =>{
const isRouteActive = index === activeTabIndex;
const tintColor = isRouteActive ? activeTintColor : inactiveTintColor;
return (
<TouchableWithoutFeedback
onPress={() => navigation.navigate(route.routeName)}
key={route.routeName}
>
<View>
<Text
style={{
fontSize: 17,
textTransform: "capitalize",
color: `${tintColor}`,
fontWeight: `${isRouteActive ? "700" : "normal"}`
}}
>
{route.routeName}
</Text>
</View>
</TouchableWithoutFeedback>
);
})}
</View>
</View>
);
};
the tabs show as they are supposed to be, but they are not clickable and cant navigate to a different page... also the home page doesnt show.
what could be the problems, or how do i configure the routes and routeName?

Related

How to set searchbar in react native

I am a new in react native i am try to set search bar in my application. To search in flatlist data. i am not able to search in flatlist data ,What is the error i don't know. how can i set how to resolve my problem please resolve my issue. i have attached the my code given below.
import React from 'react';
import { StyleSheet, FlatList, View, TouchableOpacity, Image, Text, TextInput } from 'react-native';
import { dishesData } from './DishesData';
import { SearchBar } from 'react-native-elements'
const MenuListScreen = ({ navigation }) => {
const state = {
searchText: "",
dishesData:[],
filteredData: [],
};
let search = (searchText) => {
this.setState({searchText: searchText});
let filteredData = state.dishesData.filter(function (item) {
return item.description.includes(searchText);
});
this.setState({filteredData: filteredData});
};
return (
<View style={styles.container}>
<SearchBar
round={true}
lightTheme={true}
placeholder="Search..."
autoCapitalize='none'
autoCorrect={false}
onChangeText={search}
value={state.searchText}
/>
<FlatList style={styles.list}
contentContainerStyle={styles.listContainer}
data={dishesData}
horizontal={false}
numColumns={1}
keyExtractor={(item) => {
return item.id;
}}
renderItem={({ item }) => {
return (
<TouchableOpacity
onPress={() => navigation.navigate('MenuDetail', { id: item.id })}
>
<Image
style={styles.userImage}
source={{ uri: item.imageSource }}
/>
<View style={styles.cardFooter}>
<View style={{ alignItems: "center", justifyContent: "center" }}>
<Text style={styles.name}>{item.title}</Text>
<Text style={styles.position}>{item.price}</Text>
{/* <TouchableOpacity style={styles.followButton}
onPress={() =>
props.navigation.navigate('DetailsPage', item)
}>
<Text style={styles.followButtonText}>Buy Now</Text>
</TouchableOpacity> */}
</View>
</View>
</TouchableOpacity>
)
}} />
</View>
);
};
Hi there you can filter items by using filter function and you are already doing that but for accuracy I'll suggest to do like this.
let search = (searchText) => {
this.setState({searchText: searchText});
let filteredData = state.dishesData.filter(function (item) {
return item.description.toUpperCase().includes(searchText.toUpperCase());
});
this.setState({filteredData: filteredData});
};
and to render the filtered items on Flatlist you have to toggle data array on FlatList
<FlatList style={styles.list}
contentContainerStyle={styles.listContainer}
data={state.searchText ? state.filteredData:state.dishesData}
horizontal={false}
numColumns={1}
keyExtractor={(item) => {
return item.id;
}}.../>
Here is the Snack Link you can test as well Working Example

React Native: I can't set a TextInput value from a 'child' screen

I am working in React Native and I want to set a value in a non-editable TextInput. The value is written on a screen that I am navigating to. Meaning; "parent" screen has the empty input -> I navigate to a "child" screen in which I can enter the value in another TextInput. When I have done that I want to press "OK" and go back to the "parent" screen where the value is displayed.
I have read the documentation as thoroughly as I could, but I still can't get it to work. I can set the value in the "child" screen, but the value is not updated when I navigate back to the parent.
Parent screen
Disregard the code related to equipment, since it will assimilate the barcode logic
import React, { useState } from 'react'
import { Text, TouchableOpacity, View, Image, TextInput } from 'react-native'
import styles from './styles';
import { IMAGE } from '../../constants/Images'
import { CustomHeader } from '../../CustomHeader'
export default function SamplingScreen({ navigation, route }) {
//const [barcodeData, setBarcodeData] = useState('32231321')
const [equipmentID, setEquipmentID] = useState('')
//Guarding against undefined value
const barcode = route.params?.barcode ?? 'Barcode'
return (
<View style={styles.container}>
<CustomHeader title="Sample Oil" navigation={navigation} isHome={true} ></CustomHeader>
<View style={styles.contentContainer}>
<Image
style={styles.logo}
source={IMAGE.ICON_LOGO}
/>
<Text>Send an oil sample for analysis</Text>
<Text>Start by linking a bottle with its barcode</Text>
<TouchableOpacity style={styles.button} onPress={() => navigation.navigate('BottleID')} /*barcodeData={setBarcodeData}*/ >
<Text style={styles.buttonText} >Link Bottle</Text>
</TouchableOpacity>
<Text>Please link the equipment from which the sample was taken</Text>
<TouchableOpacity style={styles.button} onPress={() => navigation.navigate('EquipmentID')} equipmentID={setEquipmentID} >
<Text style={styles.buttonText} >Link Equipment</Text>
</TouchableOpacity>
<Text>This is the bottle barcode</Text>
<TextInput
editable={false}
style={styles.input}
defaultValue={barcode}
value={barcode}
underlineColorAndroid="transparent"
autoCapitalize="none">
</TextInput>
<Text>This is the equipment barcode</Text>
<TextInput
editable={false}
style={styles.input}
defaultValue={equipmentID}
value={equipmentID}
underlineColorAndroid="transparent"
autoCapitalize="none">
</TextInput>
<TouchableOpacity style={styles.button}>
<Text style={styles.buttonText}>Accept</Text>
</TouchableOpacity>
</View>
</View>
)
}
Child screen
import React, { useState } from 'react';
import { View, Text, TouchableOpacity, TextInput } from 'react-native';
import { CustomHeader } from '../../../CustomHeader'
import styles from './styles'
export default function SetBottleIDScreen({ navigation, route }) {
const [barcodeData, setBarcodeData] = useState('')
console.log(barcodeData)
return (
<View style={styles.container} >
<CustomHeader title="Bottle ID" isHome={false} navigation={navigation} ></CustomHeader>
<Text style={{ marginTop: 30, marginBottom: 30 }} > Set barcode for sampling bottle </Text>
<TouchableOpacity style={styles.button} onPress={() => navigation.navigate('Camera')}>
<Text style={styles.buttonText}>Scan Barcode</Text>
</TouchableOpacity>
<Text style={{ marginTop: 60, marginBottom: 10 }} >Insert Barcode</Text>
<TextInput
style={styles.input}
placeholder='Barcode'
placeholderTextColor="#aaaaaa"
onChangeText={(text) => setBarcodeData(text)}
value={barcodeData}
underlineColorAndroid="transparent"
autoCapitalize="none">
</TextInput>
<TouchableOpacity style={styles.button} onPress={() => navigation.navigate('Sampling', { screen: 'Sampling', params: { barcode: barcodeData }, merge: true })}>
<Text style={styles.buttonText} >OK</Text>
</TouchableOpacity>
</View>
);
}
I am using React Navigation 5.x. I am pretty sure that the value has to be parsed as a parameter with route, but something isn't working as intended.
I solved the issue.
The syntax for setting the parameters were wrong.
It should look like this in stead:
<TouchableOpacity style={styles.button} onPress={() => navigation.navigate('Sampling', { barcode: barcodeData })}>
<Text style={styles.buttonText} >OK</Text>
</TouchableOpacity>

React Native/TypeScript - How to manage state in functional component and apply flexible style with FlatList

Can anyone tell me how to solve these things?
1.if the list is pressed, I'd like to change the background color of the list
beige(#FFF5E7) to white(#FBFBFB)
2.Also, I'd like to change the read value of the Object fales to true with useState
Problem is that if I pressed the list, whole background color of the list will be changed.
index.tsx
import React, { useState } from 'react';
import { Text, View, TouchableOpacity, FlatList } from 'react-native';
import { useNavigation } from '#react-navigation/native';
import { DETAIL } from '../../sample';
import { Object } from './sample';
export default function sample() {
const [state, setState] = useState(Object);
const navigation = useNavigation();
let Element;
const renderItem = ({ item }) => {
const readState = () => {
navigation.navigate(NOTICE_DETAIL);
const readValue = [...state];
let value = { ...readValue[0] };
value.read = true;
readValue[0] = value;
setState(readValue);
};
if (state[0].read) {
Element = (
<TouchableOpacity onPress={readState}>
<View style={[styles.row, { backgroundColor: '#FBFBFB' }]}>
<View style={styles.container}>
<View style={styles.end}>
<Text style={styles.text}>{item.text}</Text>
<Text style={styles.time}>{item.time}</Text>
</View>
<Text style={styles.content}>{item.content}</Text>
</View>
</View>
</TouchableOpacity>
);
} else {
Element = (
<TouchableOpacity onPress={readState}>
<View style={[styles.row, { backgroundColor: '#FFF5E7' }]}>
<View style={styles.container}>
<View style={styles.end}>
<Text style={styles.text}>{item.text}</Text>
<Text style={styles.time}>{item.time}</Text>
</View>
<Text style={styles.content}>{item.content}</Text>
</View>
</View>
</TouchableOpacity>
);
}
return Element;
};
}
return (
<View style={{ flex: 1 }}>
<FlatList
extraData={Object}
data={Object}
renderItem={renderItem}
/>
</View>
);
}
Object.ts
export const Object = [
{
id: 1,
text: 'testtesttest',
content: 'testtesttest'
read: false
},
{
id: 2,
text: 'testtesttest',
content: 'testtesttest'
read: false
}
id: 3,
text: 'testtesttest',
content: 'testtesttest'
read: false
}
]
We can add inline styles into the component style props along with static styles,
For Example:
<TouchableOpacity onPress={readState}>
<View style={[styles.row, { backgroundColor: item.read ? '#FBFBFB' : 'FFF5E7' }]}>
<View style={styles.container}>
<View style={styles.end}>
<Text style={styles.text}>{item.text}</Text>
<Text style={styles.time}>{item.time}</Text>
</View>
<Text style={styles.content}>{item.content}</Text>
</View>
</View>
</TouchableOpacity>
Problem in your readState function and if (state[0].read) {. You always change item with index 0 and then check state[0].read for all elements of your array.

Filtering items when a feild is pressed in react native

I have a screen with different cards (that has article information) am trying to filter the articles by categories when ever the convenient category is pressed i want that category to be selected and the articles that belong to that category to show and , on the other hand all articles from all the categories to show when no category is selected ( this will make more sense if you look at the picture bellow )
The code used to showing the pictures of the diffrent categories :
import TouchableScale from "react-native-touchable-scale";
import { category } from "../api/data";
import colors from "../config/colors";
function HotTopics({ navigation }) {
//const { width, height } = Dimensions.get("window");
return (
<View style={styles.Container}>
<View>
<Text style={styles.CategoryText}>Hot Topics</Text>
</View>
<FlatList
horizontal
showsHorizontalScrollIndicator={false}
style={{ paddingHorizontal: 15 }}
data={category}
keyExtractor={(item) => item.id}
renderItem={({ item }) => {
return (
<View>
<View>
<TouchableScale
activeScale={0.9}
tension={50}
friction={7}
useNativeDriver
onPress={() => navigation.navigate({ id: item.id })}
>
{/* to show the horizental news list*/}
<Image
source={{ uri: item.image }}
style={{
width: 100,
height: 120,
borderRadius: 16,
marginRight: 10,
}}
/>
{/* to show the news titles inside the pictures*/}
<SharedElement
id={`item.${item.id}.text`}
style={{
width: 100,
position: "absolute",
bottom: 95,
//left: 10,
paddingHorizontal: 5,
justifyContent: "center",
alignItems: "center",
}}
>
<Text style={styles.blogTitle}>{item.title}</Text>
</SharedElement>
{/* to show the pictre of the author of the news article*/}
{/* to show the name of the author and read time of article*/}
</TouchableScale>
</View>
</View>
);
}}
/>
</View>
);
}
The code used for showing the articles cards bellow : (ArticleList.js)
function ArticleList({ navigation, post }) {
if (!post.length) {
return null;
} // so we dont show anything untill we have articles
return (
<>
<View style={styles.Container}>
<Text style={styles.HeadText}>Popular</Text>
<Text style={styles.subText}>Show all</Text>
</View>
<FlatList
showsVerticalScrollIndicator={false}
data={post}
keyExtractor={(item) => item.id}
renderItem={({ item }) => {
return (
<TouchableScale
activeScale={0.9}
tension={50}
friction={7}
useNativeDriver
onPress={() =>
navigation.navigate("DetailScreen", { data: item })
}
>
<Card item={item} />
</TouchableScale>
);
}}
/>
</>
);
}
And on the main screen i call ArticleList.js and filter the data like this :
// for filtering the data
const filterResultsByCategory = (category) => {
return post.filter((onepost) => {
return onepost.category === category;
});
};
// to show the data
<ArticleListVer post={filterResultsByCategory("Politics")} />
the code used for the main screen :
import React, { useState } from "react";
import { StyleSheet, View, ScrollView, SafeAreaView } from "react-native";
import Header from "../components/Header";
import ArticleList from "../components/ArticleList";
import ArticleListVer from "../components/ArticleListVer";
import Categories from "../components/Categories";
import HotTopics from "../components/HotTopics";
import { LinearGradient } from "expo-linear-gradient";
import useArticles from "../hooks/useArticles";
import usePosts from "../hooks/usePosts";
function MainScreen({ navigation }) {
const [Category, setCategory] = useState();
const [loadApi, data, errorMessage] = useArticles();
const [loadPost, post] = usePosts();
const filterResultsByCategory = (category) => {
return post.filter((onepost) => {
return onepost.category === category;
});
};
return (
<View style={{ flex: 1 }}>
{/* header Date and title */}
<LinearGradient
colors={["#353540", "#353540", "#1E1E24"]}
style={{ width: "100%", height: "100%" }}
>
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollView}>
<Header headerTitle="TODAY'S ARTICLES" />
{/* haeder Categories */}
<Categories />
{/* show the data in a flatlist */}
<ArticleList data={data} navigation={navigation} />
{/* show the categories in a flatlist*/}
<HotTopics onCategorySelect={this.setCategory} />
{/* show the vertical Article list */}
<ArticleListVer
post={filterResultsByCategory(this.state.category)}
/>
</ScrollView>
</SafeAreaView>
</LinearGradient>
</View>
);
}
MainScreen.navigationOptions = () => {
return {
headerShown: false,
};
};
const styles = StyleSheet.create({});
export default MainScreen;
The easiest way to handle this is to have a callback function to set the state from the HotTopics component something like below
const [category, setCategory] = useState();
In render
<HotTopics onCategorySelect={setCategory} />
<ArticleListVer post={filterResultsByCategory(category)} />
for the onclick of the hottopic you can do
onPress={() =>
this.props.onCategorySelect(item.category)
}
By doing this you will re render the parent with new Category. and for reset you will need a button to reset the state to empty so that you will show all items.

Multiple Component with Same Function Name in React Native

I'm using react-native-material-menu's popup for showing menu options.
But the issue is, it's not working for multiple scenarios.
I mean when I click on first menu button, the same methods gets triggered and hence the same menu is opened every time.
What should be the better approach for to handle this particular scenario.
_menu = null;
setMenuRef = ref => {
this._menu = ref;
};
hideMenu = () => {
this._menu.hide();
};
showMenu = () => {
this._menu.show();
};
<FlatList
data={this.state.clientsList}
renderItem={({ item }) => {
return (
<View style={styles.caseItem} >
<Card style={styles.card}>
<CardItem>
<Body>
<View style={styles.rowTitle}>
<Text style={styles.title}>{item.FullName}</Text>
<Menu
ref={this.setMenuRef}
button={
<Icon
type="Feather"
name="more-vertical"
onPress={this.showMenu}
style{{fontSize:20,color:'#555'}}
/>
}>
<MenuItem onPress={this.hideMenu}>View</MenuItem>
<MenuItem onPress={this.hideMenu}>Edit</MenuItem>
<MenuItem onPress={this.hideMenu}>Delete </MenuItem>
</Menu>
</View>
<View>
<Text style={styles.lbl}>Email: <Text style={styles.lblValue}>{item.EmailID}</Text></Text>
<Text style={styles.lbl}>Client Type: <Text style={styles.lblValue}>{item.ClientType}</Text></Text>
</View>
</Body>
</CardItem>
</Card>
</View>
);
}}
keyExtractor={item => item.ID}
/>
Snack Here
To handle the states in the correct way, you will need to create a new Class which will be handling just the MenuItem
The below code will work: Here is the Snack.
import * as React from "react";
import { Text, View, StyleSheet } from "react-native";
import Constants from "expo-constants";
import { Container, Content, Card, CardItem, Body, Icon } from "native-base";
import * as Font from "expo-font";
import Menu, { MenuItem, MenuDivider } from "react-native-material-menu";
// You can import from local files
import AssetExample from "./components/AssetExample";
export default class App extends React.Component {
onView = () => {
alert("Do something here");
console.log("You can do what ever you want here");
}
render() {
return (
<View style={styles.container}>
<View style={styles.caseItem}>
<Card style={styles.card}>
<CardItem>
<Body>
<View style={styles.rowTitle}>
<Text style={styles.title}>John Doe</Text>
<CustomMenu onView={this.onView}/>
</View>
<View>
<Text style={styles.lbl}>
Email: <Text style={styles.lblValue}>john#yopmail.com</Text>
</Text>
<Text style={styles.lbl}>
Client Type: <Text style={styles.lblValue}>Individual</Text>
</Text>
</View>
</Body>
</CardItem>
</Card>
</View>
<View style={styles.caseItem}>
<Card style={styles.card}>
<CardItem>
<Body>
<View style={styles.rowTitle}>
<Text style={styles.title}>John Doe</Text>
<CustomMenu onView={this.onView}/>
</View>
<View>
<Text style={styles.lbl}>
Email: <Text style={styles.lblValue}>john#yopmail.com</Text>
</Text>
<Text style={styles.lbl}>
Client Type: <Text style={styles.lblValue}>Individual</Text>
</Text>
</View>
</Body>
</CardItem>
</Card>
</View>
<View style={styles.caseItem}>
<Card style={styles.card}>
<CardItem>
<Body>
<View style={styles.rowTitle}>
<Text style={styles.title}>John Doe</Text>
<CustomMenu onView={this.onView} />
</View>
<View>
<Text style={styles.lbl}>
Email: <Text style={styles.lblValue}>john#yopmail.com</Text>
</Text>
<Text style={styles.lbl}>
Client Type: <Text style={styles.lblValue}>Individual</Text>
</Text>
</View>
</Body>
</CardItem>
</Card>
</View>
</View>
);
}
}
class CustomMenu extends React.Component {
_menu = null;
setMenuRef = ref => {
this._menu = ref;
};
hideMenu = () => {
this._menu.hide();
};
onViewClick = () => {
const {onView} = this.props;
onView();
this.hideMenu();
}
showMenu = () => {
this._menu.show();
};
render() {
return (
<Menu
ref={this.setMenuRef}
button={
<Icon
type="Feather"
name="more-vertical"
onPress={this.showMenu}
style={{ fontSize: 20, color: "#555" }}
/>
}
>
<MenuItem onPress={this.onViewClick}>View</MenuItem>
<MenuItem onPress={this.hideMenu}>Edit</MenuItem>
<MenuItem onPress={this.hideMenu}>Delete </MenuItem>
</Menu>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
paddingTop: Constants.statusBarHeight,
backgroundColor: "#ecf0f1",
padding: 8
},
rowTitle: {
flexDirection: "row",
justifyContent: "space-between",
width: "100%"
},
title: {
fontSize: 14,
marginBottom: 5
},
lbl: {
fontSize: 11,
color: "#000"
},
lblValue: {
fontSize: 11,
color: "#555",
fontWeight: "normal"
},
caseItem: {
marginBottom: 0
}
});
Since the FlatList will iterate over the menu items, you need to maintain index for each iterable menu options.
You can check, you are passing item object within renderItems prop. So you can use the same item.id as a key to your child (iterable) component.
Since the child component now maintains an index, so now you can pass it in methods which will help you differentiate the event which got triggered from the child element.
I hope this might give you an idea about the issue.

Categories

Resources