Add and Remove items from state array with React Native Checkbox - javascript

I am trying to add and remove items from a state array using React Hooks and React Native Checkboxes. I am able to add the value of the checkbox to the array when checked, but I am unable to remove the value from the array at all, let alone when the checkbox is un checked. I have tried many different filter solutions, and do not want to use splice to avoid mutation. For now I am trying to use a separate button to delete the value from the array. Here is an expo snack https://snack.expo.dev/jN_QvE7pb
import React, {useState, useEffect, useRef} from 'react';
import {Text, View, StyleSheet, FlatList, Button, Modal, CheckBox} from 'react-native';
// import CheckBox from '#react-native-community/checkbox';
import {Card} from 'react-native-paper';
const data = [
{id: 1, txt: 'item1', isChecked: false},
{id: 2, txt: 'item2', isChecked: false},
{id: 3, txt: 'item3', isChecked: false},
{id: 4, txt: 'item4', isChecked: false},
];
const Example = () => {
const [products, setProducts] = useState(data);
const [arr, setArr] = useState([]);
useEffect(() => {
console.log(arr);
}, [arr]);
const addToArray = id => {
console.log(id);
products.map(product => {
if (id === product.id) {
setArr(prev => [...prev, product.id]);
}
});
};
const removeFromArray = id => {
setArr(arr.filter((e, i) => e.id !== id));
};
return (
<View style={styles.container}>
<FlatList
data={products}
renderItem={({item}) => (
<Card style={{margin: 5}}>
<View style={styles.card}>
<View
style={{
flexDirection: 'row',
flex: 1,
justifyContent: 'space-between',
}}>
<CheckBox
value={item.isChecked}
onChange={() => {
addToArray(item.id);
}}
/>
<Button
onPress={() => {
removeFromArray(item.id);
}}
title="Remove From Array"
/>
<Text>{item.txt}</Text>
</View>
</View>
</Card>
)}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
card: {
padding: 10,
margin: 5,
flexDirection: 'row',
justifyContent: 'space-between',
},
modalView: {
margin: 20,
backgroundColor: 'white',
borderRadius: 20,
padding: 5,
justifyContent: 'space-between',
alignItems: 'center',
elevation: 5,
},
text: {
textAlign: 'center',
fontWeight: 'bold',
},
});
export default Example;

Related

ERROR TypeError: undefined is not an object (evaluating 'state.map')

I am trying to change the state of my 'quantityCounter' but I'm getting an error as the title says. Can anyone help me with changing the state while the value also changes in the screen?
import React from 'react';
import { StyleSheet, View, Text, Button } from 'react-native';
import { useSelector } from 'react-redux';
import { selectCartItems } from '../../../../redux/reducer/cartReducer';
import { selectAllItems } from '../../../../redux/reducer/itemReducer';
const CartList = () => {
const cartItems = useSelector(selectCartItems);
const itemData = useSelector(selectAllItems);
const [quantityCounter, setQuantityCounter] = React.useState(cartItems);
function quantityHandler({id, num}){
const targetItem = itemData.find((item) => item.id === id);
let targetCart = quantityCounter.find((cart) => cart.id === id);
setQuantityCounter((previousState) =>
previousState.forEach(
(item) => {
if(item.id === id){
Object.keys(item).find(key => {
if(key === 'quantity'){
if(num === 1 && targetCart.quantity < targetItem.availableItem){
item[key] = targetCart.quantity + 1;
}
if(num === 0 && targetCart.quantity > 0) {
item[key] = targetCart.quantity - 1;
}
}
})
}
}));
}
return (
<>
{quantityCounter.map((item) => (
<View style={styles.CartItemsContainer} key={item.id}>
<Text style={styles.textStyle}>{item.productName}</Text>
<Text style={styles.textStyle}>{item.productPrice}</Text>
<View style={styles.quantityContainer}>
<Button title='-' onPress={() => quantityHandler({id : item.id, num: 0})}/>
<Text style={styles.quantityContainer__text}>{item.itemQuantity}</Text>
<Button title='+' onPress={() => quantityHandler({id : item.id, num: 1})}/>
</View>
</View>
))}
</>
)
}
const styles = StyleSheet.create({
CartItemsContainer:{
flexDirection: 'row', alignSelf: 'stretch'
},
textStyle: {
flex: 1, alignSelf: 'stretch',
borderWidth: 1, borderTopColor: 'transparent',
textAlign: 'center', textAlignVertical: 'center'
},
quantityContainer:{
flex: 1, alignSelf: 'stretch', flexDirection: 'row',
borderWidth: 1, borderTopColor: 'transparent',
alignItems: 'baseline', justifyContent: 'center'
},
quantityContainer__text:{
marginHorizontal: 5, marginVertical: 5
}
});
export default CartList;
Another approach I did was this but the state is only changing, in the screen it doesn't. When the 'quantityHandler' is being pressed, it works as what it is supposed to be but I don't know how to fix or make this work. I tried different way but I can't really show it. Please help.
import React from 'react';
import { StyleSheet, View, Text, Button } from 'react-native';
import { useSelector } from 'react-redux';
import { selectCartItems } from '../../../../redux/reducer/cartReducer';
import { selectAllItems } from '../../../../redux/reducer/itemReducer';
const CartList = () => {
const cartItems = useSelector(selectCartItems);
const itemData = useSelector(selectAllItems);
const [quantityCounter, setQuantityCounter] = React.useState(0);
let total = 0;
let id, quantity, name, price;
let cart_replica = [];
cartItems.forEach(item => {
id = item.id;
name = item.productName;
price = item.productPrice;
quantity = item.itemQuantity;
total += item.totalPrice;
cart_replica.push({id, name, quantity, price})
});
function quantityHandler({id, num}){
const targetItem = itemData.find((item) => item.id === id);
let targetCart = cart_replica.find((cart) => cart.id === id);
cart_replica.map(
(item) => {
if(item.id === id){
return { ...cart_replica, item: { ...item, quantity: item.quantity + 1}};
}
});
console.log(cart_replica[0])
}
return (
<>
{cart_replica.map((item) => (
<View style={styles.CartItemsContainer} key={item.id}>
<Text style={styles.textStyle}>{item.name}</Text>
<Text style={styles.textStyle}>{item.price}</Text>
<View style={styles.quantityContainer}>
<Button title='-' onPress={() => quantityHandler({id : item.id, num: 0})}/>
<Text style={styles.quantityContainer__text}>{item.quantity}</Text>
<Button title='+' onPress={() => quantityHandler({id : item.id, num: 1})}/>
</View>
</View>
))}
</>
)
}
const styles = StyleSheet.create({
CartItemsContainer:{
flexDirection: 'row', alignSelf: 'stretch'
},
textStyle: {
flex: 1, alignSelf: 'stretch',
borderWidth: 1, borderTopColor: 'transparent',
textAlign: 'center', textAlignVertical: 'center'
},
quantityContainer:{
flex: 1, alignSelf: 'stretch', flexDirection: 'row',
borderWidth: 1, borderTopColor: 'transparent',
alignItems: 'baseline', justifyContent: 'center'
},
quantityContainer__text:{
marginHorizontal: 5, marginVertical: 5
}
});
export default CartList;
Can you check this ,ive added state manipulation.
Hope it helps :)
https://snack.expo.dev/5vfUoenH3
import React from 'react';
import { StyleSheet, View, Text, Button, SafeAreaView } from 'react-native';
const App = () => {
const [quantityCounter, setQuantityCounter] = React.useState([
{
id: 1,
name: 'item 1',
availableItem: 5,
price: 500,
quantity: 5,
},
{
id: 2,
name: 'item 2',
availableItem: 4,
price: 500,
quantity: 4,
},
{
id: 3,
name: 'item 3',
availableItem: 3,
price: 500,
quantity: 3,
},
]);
const quantityHandler = (id,index,isIncrement) =>{
const newCopy = [...quantityCounter];
if(isIncrement){
newCopy[index].quantity = newCopy[index].quantity +1;
}else {
newCopy[index].quantity = newCopy[index].quantity -1;
}
console.log("er",newCopy,index)
setQuantityCounter(newCopy)
}
return (
<SafeAreaView style={styles.safeStyle}>
{quantityCounter.map((item,index) => (
<View style={styles.CartItemsContainer} key={item.id}>
<Text style={styles.textStyle}>{item.name}</Text>
<Text style={styles.textStyle}>{item.price}</Text>
<View style={styles.quantityContainer}>
<Button title='-' onPress={() => quantityHandler(item.id,index,false)}/>
<Text style={styles.quantityContainer__text}>{item.quantity}</Text>
<Button title='+' onPress={() => quantityHandler(item.id,index,true)}/>
</View>
</View>
))}
</SafeAreaView>
)
}
const styles = StyleSheet.create({
safeStyle: {
marginTop:'5%'
},
CartItemsContainer:{
flexDirection: 'row', alignSelf: 'stretch'
},
textStyle: {
flex: 1, alignSelf: 'stretch',
borderWidth: 1, borderTopColor: 'transparent',
textAlign: 'center', textAlignVertical: 'center'
},
quantityContainer:{
flex: 1, alignSelf: 'stretch', flexDirection: 'row',
borderWidth: 1, borderTopColor: 'transparent',
alignItems: 'baseline', justifyContent: 'center'
},
quantityContainer__text:{
marginHorizontal: 5, marginVertical: 5
}
});
export default App;

Why sorting of the Flatlist is not appearing? in react native

I am currently making sorting order in Ascending and Descending but the flatlist is not appearing.
I want to show sorting order by recently added, low to high & high to low by each separate buttons.
please help.
below is my code:
const [ demoList, setdemoList ] = useState([
{id: 3, name: 'Omkar'},
{id: 2, name: 'Abhishek'},
{id: 1, name: 'Saurabh'},
{id: 1, name: 'Saurabh'},
{id: 4, name: 'Chintan'},
{id: 6, name: 'Hardik'},
{id: 5, name: 'Lalit'},
]);
const sortListById = () => {
demoList.sort(function (obj1, obj2) {
return obj1.id - obj2.id;
});
};
return (
<View style={styles.container}>
<View style={{ margin: 10,alignItems: 'center',justifyContent: 'center',}}>
<FlatList data={demoList}
extraData={setdemoList}
renderItem={({ item }) => (
<View style={{ flexDirection: 'row' }}>
<Text style={{ fontSize: 20, margin: 15 }}>{item.id}</Text>
<Text style={{ fontSize: 20, margin: 15 }}>{item.name}</Text>
</View>
)}
keyExtractor={(item, index) => index}
/>
<View style={{ flex: 1 }}>
<Button title="Sort List" onPress={sortListById} />
</View>
</View>
</View>
);
full code is here: https://snack.expo.dev/#john.ocean/16c137
Working Example: Expo Snack, here you can sort by both ASC and DEC order.
Output:
Solution:
import React, { useState } from 'react';
import { StyleSheet, Text, View, FlatList, Button } from 'react-native';
let data = [
{ id: 3, name: 'Omkar' },
{ id: 2, name: 'Abhishek' },
{ id: 1, name: 'Saurabh' },
{ id: 1, name: 'Saurabh' },
{ id: 4, name: 'Chintan' },
{ id: 6, name: 'Hardik' },
{ id: 5, name: 'Lalit' },
];
export default function Home() {
const [demoList, setdemoList] = useState([...data]);
const [order, setOrder] = useState(1);
const sortListASC = () => {
demoList.sort((obj1, obj2) => {
return obj1.id - obj2.id;
});
setdemoList([...demoList]); // update
};
const sortListDES = () => {
demoList.sort((obj1, obj2) => {
return obj2.id - obj1.id;
});
setdemoList([...demoList]);
};
return (
<View style={styles.container}>
<View
style={{ margin: 10, alignItems: 'center', justifyContent: 'center' }}>
<FlatList
data={demoList}
renderItem={({ item }) => (
<View style={{ flexDirection: 'row' }}>
<Text style={{ fontSize: 20, margin: 15 }}>{item.id}</Text>
<Text style={{ fontSize: 20, margin: 15 }}>{item.name}</Text>
</View>
)}
keyExtractor={(item, index) => index}
/>
<View style={{ flex: 1, flexDirection: 'row' }}>
<View style={{ marginLeft: 10 }}>
<Button title={'ASC'} onPress={sortListASC} />
</View>
<View style={{ marginLeft: 10 }}>
<Button title={'DEC'} onPress={sortListDES} />
</View>
<View style={{ marginLeft: 10 }}>
<Button title={'Default'} onPress={() => setdemoList([...data])} />
</View>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
});
Use this to avoid data mutation.
const sortListById = () => setdemoList([...demoList].sort( (obj1, obj2)=>obj1.id - obj2.id))
If you use this
demoList.sort((obj1, obj2) =>{
return obj1.id - obj2.id;
});
this will change the value of demoList

How to update object Array State and screen style on touchable item click in react native

I am a bit new to react native and I am having difficulty updating object Array State and screen style on button item click during run time in react native
I tried using useState but the style does not change at run time on the touchable item click
Please advise me on the right way to change the screens view style on item click
see my code below
import React, {useState} from 'react';
import {ScrollView, FlatList, View, Text, TouchableOpacity} from 'react-native';
import styles from './styles';
export default function Loans({}) {
const [selectedDurationId, setSelectedDurationId] = useState(1);
const [selectedAmountId, setSelectedAmountId] = useState(1);
const changeSelectedDuration = function (id) {
console.log('before selected Duration');
console.log(id);
//change all the selecteds to no
durationArray.forEach(function (arrayItem) {
var x = (arrayItem.selected = 'no');
console.log(x);
setSelectedDurationId(id);
updateDataArray(durationArray, selectedDurationId);
console.log('after selected Duration');
});
};
const changeSelectedAmount = function (id) {
console.log('before selected Amount');
console.log(id);
//change all the selecteds to no
loanAmountArray.forEach(function (arrayItem) {
var x = (arrayItem.selected = 'no');
console.log(x);
});
setSelectedAmountId(id);
updateDataArray(loanAmountArray, selectedAmountId);
console.log('after selected Amount');
};
const updateDataArray = function (array, id) {
array.forEach(function () {
//change selected to yes where id == id
if (array.id === id) {
var x = (array.selected = 'yes');
console.log(x);
}
});
};
const loanAmountArray = [
{
id: 1,
amount: '5,000',
selected: 'yes',
},
{
id: 2,
amount: '10,000',
selected: 'no',
},
{
id: 3,
amount: '20,000',
selected: 'no',
},
];
const durationArray = [
{
id: 1,
days: '30 days',
rate: '3.3% Interest',
selected: 'yes',
},
{
id: 2,
days: '60 days',
rate: '5% Interest',
selected: 'no',
},
{
id: 3,
days: '90 days',
rate: '7% Interest',
selected: 'no',
},
];
return (
<View style={{flex: 1}}>
<ScrollView>
<View style={styles.contain}>
<Text>Chose Loan Amount</Text>
<FlatList
numColumns={6}
data={loanAmountArray}
keyExtractor={(item, index) => {
console.log('index', index);
return index.toString();
}}
renderItem={({item}) => {
console.log('item', item);
return (
<View>
<TouchableOpacity
onPress={() => {
changeSelectedAmount(item.id);
}}>
<Text
style={
item.selected === 'yes'
? styles.textBoxSelected
: styles.textBox
}>
{item.amount}
</Text>
</TouchableOpacity>
</View>
);
}}
/>
<Text>Chose Payment Duration</Text>
<FlatList
numColumns={3}
data={durationArray}
keyExtractor={(item, index) => {
console.log('index', index);
return index.toString();
}}
renderItem={({item}) => {
console.log('item', item);
return (
<View>
<TouchableOpacity
style={
item.selected === 'yes'
? styles.durationViewPressed
: styles.durationView
}
onPress={() => {
changeSelectedDuration(item.id);
}}>
<View>
<Text style={styles.interest}>{item.rate}</Text>
</View>
<View>
<Text style={styles.days}>{item.days}</Text>
</View>
</TouchableOpacity>
</View>
);
}}
/>
</View>
</ScrollView>
</View>
);
}
here's the style below
import {StyleSheet} from 'react-native';
export default StyleSheet.create({
textBox: {
marginTop: 13,
marginBottom: 30,
paddingTop: 10,
paddingLeft: 16,
paddingRight: 6,
fontSize: 18,
borderColor: '#1a2856',
borderWidth: 5,
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
borderBottomLeftRadius: 20,
borderBottomRightRadius: 20,
},
textBoxSelected: {
marginTop: 13,
marginBottom: 30,
paddingTop: 10,
paddingLeft: 16,
paddingRight: 6,
fontSize: 18,
backgroundColor: '#1a2856',
color: '#fff',
borderWidth: 5,
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
borderBottomLeftRadius: 20,
borderBottomRightRadius: 20,
},
durationView: {
marginTop: 10,
marginBottom: 20,
paddingLeft: 5,
paddingRight: 5,
},
durationViewPressed: {
marginTop: 10,
marginBottom: 20,
paddingLeft: 5,
paddingRight: 5,
borderColor: '#1a2856',
borderWidth: 5,
},
interest: {
color: '#fff',
backgroundColor: '#1a2856',
paddingLeft: 5,
paddingRight: 5,
},
days: {
borderColor: '#1a2856',
borderWidth: 5,
paddingTop: 10,
paddingLeft: 16,
paddingRight: 6,
fontSize: 18,
},
});
Issues
Both loanAmountArray and durationArray are defined in the function body, so they are actually redeclared each render cycle, so any mutations you thought you did in the previous render cycle are wiped out. When this happens the style attribute is never able to match anything different each render.
Solution
Since it seems you don't really update the elements of the array you can move the arrays out of the component. They can remain const and won't be redeclared each render.
Don't bother trying to update the selected property of each element in the array, you can easily derive the selected state from the selectedDurationId and selectedAmountId state values and the current item.id when rendering.
Use the extraData prop to indicate the list should rerender.
Code:
const loanAmountArray = [
{
id: 1,
amount: "5,000",
selected: "yes"
},
{
id: 2,
amount: "10,000",
selected: "no"
},
{
id: 3,
amount: "20,000",
selected: "no"
}
];
const durationArray = [
{
id: 1,
days: "30 days",
rate: "3.3% Interest",
selected: "yes"
},
{
id: 2,
days: "60 days",
rate: "5% Interest",
selected: "no"
},
{
id: 3,
days: "90 days",
rate: "7% Interest",
selected: "no"
}
];
export default function Loans({}) {
const [selectedDurationId, setSelectedDurationId] = useState(1);
const [selectedAmountId, setSelectedAmountId] = useState(1);
const changeSelectedDuration = function (id) {
setSelectedDurationId(id);
};
const changeSelectedAmount = function (id) {
setSelectedAmountId(id);
};
return (
<View style={{ flex: 1 }}>
<ScrollView>
<View style={styles.contain}>
<Text>Chose Loan Amount</Text>
<FlatList
numColumns={6}
data={loanAmountArray}
extraData={selectedAmountId} // <-- prop used to rerender
keyExtractor={(item, index) => {
return index.toString();
}}
renderItem={({ item }) => {
return (
<View>
<TouchableOpacity
onPress={() => {
changeSelectedAmount(item.id);
}}
>
<Text
style={
item.id === selectedAmountId // <-- match id property
? styles.textBoxSelected
: styles.textBox
}
>
{item.amount}
</Text>
</TouchableOpacity>
</View>
);
}}
/>
<Text>Chose Payment Duration</Text>
<FlatList
numColumns={3}
data={durationArray}
extraData={selectedDurationId} // <-- prop used to rerender
keyExtractor={(item, index) => {
return index.toString();
}}
renderItem={({ item }) => {
return (
<View>
<TouchableOpacity
style={
item.id === selectedDurationId // <-- match id property
? styles.durationViewPressed
: styles.durationView
}
onPress={() => {
changeSelectedDuration(item.id);
}}
>
<View>
<Text style={styles.interest}>{item.rate}</Text>
</View>
<View>
<Text style={styles.days}>{item.days}</Text>
</View>
</TouchableOpacity>
</View>
);
}}
/>
</View>
</ScrollView>
</View>
);
}
Expo Snack Demo

React native flatlist multiple selection is not updating

I am using a flatlist to expose all the list of ingredients I have saved on my database, but once I update the state, it is not reflecting on the flatlist component.
The flatlist component
<FlatList
horizontal
bounces={false}
key={ingredientList.id}
data={ingredientList}
renderItem={({ item }) => (
<TouchableOpacity onPress={() => selectedIngredient(item)}>
<Card key={item.id}>
<Text key={item.title} style={styles.titleText}>{item.name}</Text>
<Text key={item.title} style={styles.titleText}>{item.isSelected?'selected':'not selected'}
</Text>
<ImageBackground key={item.illustration} source={item.illustration} style={styles.cardImage}>
</ImageBackground>
</Card>
</TouchableOpacity>
)}
keyExtractor={(item) => item.index}
/>
This is the function that find the selected item "selectedIngredient"
function selectedIngredient(item) {
console.log('received: ', item.name)
item.isSelected = !item.isSelected;
return { ...item.isSelected }
}
That component call is working when I try debbug with console.log after the "item.isSelected = !item.isSelected", but the IU is not updated. Can someone help me to understand how to fix it?
You need to set state by using either setState in a class-based component or either using useState hook in the functional component.
function selectedIngredient(item) {
console.log('received: ', item.name)
item.isSelected = !item.isSelected; //this is not how you set state
return { ...item.isSelected }
}
Screenshot:
here is our old example which I modified for your current scenario:
import React, { useState } from 'react';
import {
Text,
View,
StyleSheet,
FlatList,
TouchableOpacity,
} from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
// or any pure javascript modules available in npm
const ingredientList = [
{
id: 1,
name: 'item1',
selected: false,
},
{
id: 2,
name: 'item 2',
selected: false,
},
{
id: 3,
name: 'item 3',
selected: false,
},
{
id: 8,
name: 'item 4',
selected: false,
},
{
id: 4,
name: 'item 5',
selected: false,
},
{
id: 5,
name: 'item 6',
selected: false,
},
];
export default function App() {
const [selectedItem, setSelectedItem] = useState(null);
const [allItems, setAllItems] = useState(ingredientList);
const selectedIngredient = (item) => {
console.log('selecionado: ' + item.name);
setSelectedItem(item);
/* Below operation can be improved by passing index to the function itself.
so filtering would not be required
*/
let temp = allItems.filter((parentItem) => parentItem.id !== item.id);
item.selected = !item.selected;
temp = temp.concat(item);
temp.sort((a, b) => parseInt(a.id) - parseInt(b.id));
setAllItems(temp);
console.log(allItems);
};
return (
<View style={styles.container}>
<FlatList
style={styles.flatlist}
horizontal
bounces={false}
data={allItems}
renderItem={({ item }) => (
<TouchableOpacity
style={styles.flatListItem}
key={item.id}
onPress={() => selectedIngredient(item)}>
<Text>{item.name}</Text>
{!item.selected ? (
<Text style={{ color: 'red' }}>{'Not Selected'}</Text>
) : (
<Text style={{ color: 'green' }}>{'Selected'}</Text>
)}
</TouchableOpacity>
)}
keyExtractor={(item) => item.index}
/>
{selectedItem ? (
<View style={styles.selectedTextView}>
<Text style={styles.selectedText}>{`${selectedItem.name} ${
selectedItem.selected ? 'selected' : 'not selected'
}`}</Text>
</View>
) : (
<View style={styles.selectedTextView}>
<Text style={styles.selectedText}>{`Nothing selected`}</Text>
</View>
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
flatListItem: {
width: 100,
height: 100,
backgroundColor: 'white',
margin: 5,
borderRadius: 10,
justifyContent: 'center',
alignItems: 'center',
},
selectedTextView: {
flex: 8,
backgroundColor: 'white',
margin: 5,
borderRadius: 10,
justifyContent: 'center',
alignItems: 'center',
fontSize: 20,
},
selectedText: {
fontSize: 30,
},
});
Live Demo

underline the clicked text element

I have a list of text elements that I want to underline when clicked. If I add the text decoration to the tabText then obviously it is applied to all items. How can I make sure that the when I click on another tab, the underline from the previous tab gets removed?
Is there any way I can add or remove items from the style element upon clicking on an item?
//onPress={() => {}}>
const tabs = [
{
id: 1,
text: 'Alle List',
},
{
id: 2,
text: 'Second',
},
];
export const Tab: React.FunctionComponent = () => {
return (
<View style={styles.tabView}>
{tabs.map((item: any) => (
<View>
<Text style={styles.tabText}>{item.text}</Text>
</View>
))}
</View>
);
};
const styles = StyleSheet.create({
tabView: {
paddingTop: moderateScale(15),
paddingLeft: moderateScale(20),
paddingRight: moderateScale(20),
flexDirection: 'row',
justifyContent: 'space-between',
},
tabText: {
color: 'white',
paddingBottom: moderateScale(10),
//textDecorationLine: 'underline'
},
});
Codesandbox (with tabText items as an array too):
https://snack.expo.io/#nhammad/shallow-watermelon
You can use useState to save the selected index and then apply another style based on the selected index. Here is a quick modification to your script and the snack link is at the end.
import * as React from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
const tabs = [
{
id: 1,
text: 'All Friends',
},
{
id: 2,
text: 'Second',
},
{
id: 3,
text: 'Third',
},
];
export default function App() {
const [selected, setSelected] = React.useState(null)
return (
<View style={styles.container}>
<View style={styles.tabView}>
{tabs.map((item: any, index) => (
<TouchableOpacity onPress={()=>setSelected(index)}>
<View>
<Text style={[styles.tabText,selected===index?styles.selected:null]}>{item.text}</Text>
</View>
</TouchableOpacity>
))}
</View>
</View>
);
}
const styles = StyleSheet.create({
tabView: {
paddingTop: 15,
paddingLeft: 20,
paddingRight: 20,
flexDirection: 'row',
justifyContent: 'space-between',
},
tabText: {
color: 'black',
paddingBottom: 10,
},
selected: {
textDecorationLine: 'underline'
},
});
https://snack.expo.io/#saachitech/da6280
You can add different styles for your tab depending on active route
<Text style={[(this.props.activeRouteName == route.routeName) ? styles.tabActiveText: styles.tabText]}>{item.text}</Text>
And then in the styles
tabActiveText: {
color: 'white',
paddingBottom: moderateScale(10),
textDecorationLine: 'underline'
}

Categories