output
code
import React from 'react';
import {
Text,
View,
FlatList,
ScrollView,
SafeAreaView
} from 'react-native';
import { nameData } from './dummydata';
const windowSize = FlatList.length > 50 ? FlatList.length / 4 : 21;
const Main = () => {
return (
<View style={{}}>
<SafeAreaView style={{}}>
<ScrollView style={{}}>
<FlatList
disableVirtualization={true}
//data={nameData.sort((a, b) => a.name.localeCompare(b.name))}
data={nameData.sort(function (a, b) {
return (a.name < b.name) ? -1 : (a.name > b.name) ? 1 : 0;
})}
renderItem={({ item }) => (
<Text style={{ fontSize: 20,marginLeft:10,padding:5 }}>{item.name}</Text>
)}
getItemLayout={(data, index) => ({
length: 80,
offset: 80 * index,
index,
})}
removeClippedSubviews={true}
maxToRenderPerBatch={windowSize}
windowSize={windowSize}
numColumns={1}
keyExtractor={(item, index) => String(index)}
contentContainerStyle={{ paddingBottom: 10 }}
/>
</ScrollView>
</SafeAreaView>
</View>
);
};
export default Main;
I have given the code above
my data is sorted , I want like this if data is started A alphabet then this data contain in A header section if data is started B alphabet then this data contain in B header section.
like this D header contain only D Starting data C header contain only C Starting data
but I don't know how to set header and how to set data in header section.
in sort I want like this data
anybody can give me solution?
thank you!š¼
Method 1
Try this package react-native-section-alphabet-list
A simple React Native component that takes an array of data and renders a SectionList with alphabetically (or custom) sorted data.
Method 2
Update your code like below and try
import React, { useEffect, useState } from "react";
import { Text, View, FlatList, SafeAreaView } from "react-native";
import { nameData } from "./duumydata";
const windowSize = FlatList.length > 50 ? FlatList.length / 4 : 21;
const Main = () => {
let listData = new Array(26).fill([]);
const headerArray = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
const [data, setData] = useState([]);
useEffect(() => {
nameData.sort(function (a, b) {
return a.name.toUpperCase() < b.name.toUpperCase()
? -1
: a.name > b.name
? 1
: 0;
});
headerArray.forEach((header, index) => {
nameData.forEach((item) => {
const headerText = item.name.split("")[0].toUpperCase();
if (header == headerText) {
listData[index] = [...listData[index], item];
}
});
});
setData(listData);
}, []);
const renderItem = ({ item, index }) => {
return (
<>
<View style={{ backgroundColor: "grey" }}>
<Text>{headerArray[index]}</Text>
</View>
{item?.map((obj) => renderName(obj))}
</>
);
};
const renderName = (item) => {
return (
<View>
<Text>{item.name}</Text>
</View>
);
};
return (
<View style={{}}>
<SafeAreaView style={{}}>
<FlatList
disableVirtualization={true}
data={data}
renderItem={(item) => renderItem(item)}
getItemLayout={(data, index) => ({
length: 80,
offset: 80 * index,
index
})}
removeClippedSubviews={true}
maxToRenderPerBatch={windowSize}
windowSize={windowSize}
numColumns={1}
keyExtractor={(item, index) => String(index)}
contentContainerStyle={{ paddingBottom: 10 }}
/>
</SafeAreaView>
</View>
);
};
export default Main;
Related
So into the cartscreen, I am importing a dropdown component.
Now, there is a different dropdown inside the cartscreen called renderDropdown, and I'm using it to display two different data lists as two dropdowns for the user to choose from. Although this renderDropdown is functioning properly, selecting an imported dropdown causes the selected value in my renderDropdown to be cleared from the dropdown bar.
I verified that renderDropdown's value remains in the current state and I noticed that when I click on this imported drop-down, I get a message printed to the console(I have added console.log in cart screen whenever screen renders), which indicates that my entire screen is rendering. Could someone please look into this and let me know what's wrong?
Here is the code for a dropdown menu.
[I've also used the same component in a lot of other screens, and it works just fine]
import { StyleSheet, View } from 'react-native'
import React from 'react'
import { Dropdown} from 'react-native-element-dropdown'
import { COLORS } from '../constants'
const DropdownComponent = ({text, extractorValue, external_Id, data:mainData, extraData, value, setValue, isFocus, setIsFocus,area=false, retailer=false, retailerC=false, extraStyling}) => {
return (
<View style={[styles.container, {...extraStyling}]}>
<Dropdown
style={[styles.dropdown, isFocus && { borderColor: COLORS.blue90 }]}
placeholderStyle={styles.placeholderStyle}
selectedTextStyle={styles.selectedTextStyle}
inputSearchStyle={styles.inputSearchStyle}
iconStyle={styles.iconStyle}
data={mainData}
containerStyle={{
backgroundColor:COLORS.white10,
borderRadius:10,
marginTop:10,
borderColor:COLORS.gray10,
shadowColor:COLORS.blue90,
shadowOffset:{
height:15,
width: 15
},
elevation:19,
}}
search
maxHeight={300}
labelField={extractorValue ? extractorValue :"name"}
valueField={external_Id ? external_Id :"name"}
placeholder={!isFocus ? `Select ${text ? text : 'Item'}` : '...'}
searchPlaceholder="Search..."
value={value}
onFocus={() => setIsFocus(true)}
onBlur={() => setIsFocus(false)}
onChange={item => {
retailer ?
retailerC ?
(
setValue({...extraData, retailerClass:external_Id ? item[external_Id] : item.name})
):
(
( area ?
setValue({...extraData, area:external_Id ? item[external_Id] : item.name})
:
setValue({...extraData, route:external_Id ? item[external_Id] : item.name})
)
)
:
(
setValue(external_Id ? item[external_Id] : item.name)
)
setIsFocus(false)
}}
/>
</View>
)
}
export default DropdownComponent
and here is the cartScreen code which is causing trouble , also i want to include that i have to show 3 dropdowns on the screen so i was using the same component renderDropdown for all of them but i was having the same issue so i though it is because of third dropwdown (namely value scheme ) so i used external one but having the same issue.
const CartDetailsScreen = ({navigation}) => {
const [loading, setLoading] = React.useState(false)
const {cartItems, setCartItems } = useContext(mapContext)
const { createOrders, createOrderStatus, distributors, setDistributors, getDistributors, schemes, setSchemes, getSchemes} = useContext(commonUrlsContext)
useLayoutEffect(()=>{
navigation.setOptions({
headerShown:true,
headerTitle:'CART DETAILS',
...HeaderStyles,
headerLeft: () =>(
<HeaderLeft navigation={navigation} />
)
})
},[])
const [valueSchemeFromDropDown, setValueSchemeFromDropDown] = React.useState('')
React.useEffect(()=>{
getSchemes()
getDistributors()
return () =>{
setDistributors([])
setSchemes([])
}
},[])
React.useEffect(()=>{
if(createOrderStatus){
ToastAndroid.show('Order created successfully', ToastAndroid.CENTER)
navigation.dispatch(
CommonActions.reset({
index: 0,
routes: [
{ name: 'OrderSuccessful' },
],
})
);
setTimeout(()=>{{navigation.navigate('OrderSuccessful'), setCartItems([])}},1000)
}
},[createOrderStatus])
function RenderDropDown({index, text, data, external_Id, extractorValue, width, qtyScheme, valueScheme}){
return(
<View style={[styles.container, width && {width: width}]}>
<Dropdown
style={[styles.dropdown]}
placeholderStyle={styles.placeholderStyle}
selectedTextStyle={styles.selectedTextStyle}
inputSearchStyle={styles.inputSearchStyle}
iconStyle={styles.iconStyle}
data={data}
containerStyle={{
borderRadius:10,
marginTop:10,
borderColor:COLORS.gray10,
shadowColor:COLORS.gray90,
shadowOffset:{
height:10,
width: 10
},
elevation:15,
}}
search
maxHeight={300}
labelField={extractorValue ? extractorValue :"name"}
valueField={external_Id ? external_Id :"name"}
placeholder={`Select ${text ? text : 'item'}`}
searchPlaceholder="Search..."
// value={qtyScheme ? cartItems[index]?.distributorName}
onChange={item => {
qtyScheme ?
(
console.log(1),
cartItems[index].qtyScheme = item[external_Id],
setCartItems(cartItems)
)
:
(
console.log(2),
cartItems[index].distributorName = item[extractorValue],
cartItems[index].distributorId = item[external_Id],
setCartItems(cartItems)
)
}}
/>
</View>
)
}
const removeFromCart = (id) =>{
let updatedCart = cartItems.filter(product => product?.products?.Id !== id)
setCartItems(updatedCart)
ToastAndroid.show('Item Removed From the Cart.', ToastAndroid.SHORT)
if(updatedCart.length === 0){
navigation.goBack()
}
}
const submitHandler = () =>{
setLoading(true)
createOrders(cartItems, valueSchemeFromDropDown)
}
const reduceHandler = (item, index) =>{
if(item.qty === 1){
let newResults = cartItems.filter(product => product.products.Id !== item.products.Id)
setCartItems(newResults)
if(newResults.length === 0){
navigation.goBack()
}
}
else{
item.qty = item.qty - 1
let newResults = cartItems.filter(product => product.products.Id !== item.products.Id ? product : item)
setCartItems(newResults)
}
}
const [testValue, setTestValue] = React.useState('')
const [testFocus, setTestFocus] = React.useState(false)
const incrementHandler = (item, index) =>{
let newResults = cartItems.map(product =>
product.products.Id === item.products.Id ? {...item, qty: product.qty + 1} : product)
setCartItems(newResults)
}
return (
<>
{ loading ?
<RowCenter style={{flex:1, flexDirection: 'column', alignItems:'center'}}>
<StyledText fontSize={'20px'}>{createOrderStatus ? 'Redirecting..' : 'Loading..'}</StyledText>
</RowCenter> :
<>
<View style={{flex:0.8}}>
<ScrollView showsVerticalScrollIndicator={false}>
{cartItems?.map((item, index)=>{
return(
<View key={item?.products?.Id} style={{flexDirection:'row', padding:13, borderRadius:10, margin:10, alignItems:'center', backgroundColor:COLORS.green20, ...customShadow }}>
<View style={{width:'100%'}}>
<StyledText>Product Name : {item?.products?.Name}</StyledText>
<ExtraSpace />
{item?.products?.Description &&
<StyledText>Product Description : {item?.products?.Description?.length > 30 ? item?.products?.Description?.slice(0,30) + '...': item?.products?.Description }</StyledText>
}
<ExtraSpace />
<View style={{flexDirection:'row', justifyContent:'space-between', alignItems:'center', padding:10}}>
<TouchableOpacity onPress={()=>removeFromCart(item?.products?.Id)} style={{flexDirection:'row', justifyContent:'center', alignItems:'center'}}>
<SimpleLineIcons name="trash" size={15} color={COLORS.error} />
<StyledText color={COLORS.error}>Remove</StyledText>
</TouchableOpacity>
<View style={{width:'40%', flexDirection:'row', justifyContent:'space-between', alignItems:'center',}}>
<TouchableOpacity onPress={()=>reduceHandler(item, index)}>
<Feather name="minus-circle" size={22} color={COLORS.gray90} />
</TouchableOpacity>
<StyledText>Qty : {item?.qty}</StyledText>
<TouchableOpacity onPress={()=>incrementHandler(item, index)} >
<Feather name="plus-circle" size={22} color={COLORS.gray90} />
</TouchableOpacity>
</View>
</View>
<RenderDropDown index={index} text={'Distributor'} data={distributors?.response} external_Id='external_Id' extractorValue='name' />
{item.distributorName &&
<Label color={'#131821'}> Clone Selected : {item.distributorName}</Label>
}
<RenderDropDown id={item?.products?.id} index={index} text={'Quantity Scheme'} data={schemes?.response?.filter(scheme => scheme.Type__c === 'Quantity Scheme')} external_Id='Id' extractorValue='Name' qtyScheme={true}/>
</View>
</View>
)
})}
</ScrollView>
</View>
<View style={{flex:0.2, justifyContent:'center', alignItems:'center', borderWidth:1, borderTopLeftRadius:10, borderTopRightRadius:10, marginBottom:2, marginHorizontal:1, borderTopColor:'gray', backgroundColor:"transparent"}}>
<DropdownComponent text={'Value Scheme'} data={schemes?.response?.filter(scheme => scheme.Type__c === 'Value Scheme')} external_Id='Id' extractorValue={'Name'} value={testValue} setValue={setTestValue} isFocus={testFocus} setIsFocus={setTestFocus} extraStyling={{width: '100%', marginTop:10, marginBottom:1}}/>
{/* <RenderDropDown text={'Value Scheme'} data={valueScheme} external_Id='Id' extractorValue='Name' valueScheme={true}/> */}
<TextButton onPress={()=>{cartItems?.length === 0 ? null : submitHandler()}} componentStyling={{width:'94%', padding:8, marginHorizontal:10, marginBottom:10, marginTop:1}} title='Place Order'/>
</View>
</>
}
</>
)
}
Hey you have added these
onFocus={() => setIsFocus(true)}
onBlur={() => setIsFocus(false)}
and these are setStates , so it will re render when dropdwon opens or closes
Hope it helps. feel free for doubts
The intended functionality is as follows:
Select an item in the list by pressing (calls onPressSport())
The item's value is stored in the sport state
When the next button is pressed, onPressNext() is called (which calls a function from context)
The problem occurs in Step 3 when I log the value of sport. Before onPressNext() is called, the value is logged as a non-NULL value; however, the log within onPressNext() is always null.
Here is the code:
import React, { useEffect, useState, useContext } from 'react'
import {
StyleSheet,
Text,
View,
Pressable,
TextInput,
KeyboardAvoidingView,
FlatList,
} from 'react-native'
import { Feather } from '#expo/vector-icons'
import userContext from '../../context/user/userContext'
import gameContext from '../../context/game/gameContext'
import { SPORTS } from '../../sample_data'
import { doHaptics } from '../../functions'
import ErrorAlert from '../../ErrorAlert'
const CreateGame_Sport = ({navigation, route}) => {
const {game, new_selectSport} = useContext(gameContext)
// const {sport} = game
const [search, setSearch] = useState('')
const [results, setResults] = useState([])
const [error, setError] = useState(null)
const [sport, setSport] = useState(game?.sport || null)
useEffect(() => {
navigation.setOptions({
title: 'Pick a sport',
headerLeft: () => (
<Pressable style={hStyles.backButton} onPress={onPressBack} hitSlop={16}>
<Feather name="chevron-left" size={28} color="#212121"/>
</Pressable>
),
headerRight: () => (
<Pressable style={hStyles.nextButton} onPress={onPressNext} hitSlop={16}>
<Text style={hStyles.nextButtonText}>Next</Text>
</Pressable>
),
})
}, [navigation])
useEffect(() => {
if (!search)
return setResults([])
const filtered = SPORTS.filter(({name}) => name.toLowerCase().includes(search.toLowerCase()))
setResults(filtered)
}, [search])
useEffect(() => {
console.log('Sport updated!')
console.log(sport)
}, [sport])
const onPressBack = () => navigation.pop()
const onPressClear = () => {
setSearch('')
setResults([])
}
const onPressSport = (val) => setSport(val)
const onPressNext = async () => {
console.log('sport: ', sport)
if (!sport) {
await doHaptics('medium')
return setError('Please select a sport!')
}
new_selectSport(sport)
return navigation.push('CreateGame_Type')
}
const onEndReached = async () => {}
const renderItem = ({item}, index) => {
const {_id, name, icon: Icon} = item
const selected = sport?._id === _id
return (
<Pressable style={selected ? styles.resultAdded : styles.result} onPress={() => onPressSport(item)}
key={_id}>
<View style={styles.resultColumn}>
<Text style={styles.resultName}>{name}</Text>
</View>
<Icon style={styles.resultIcon}/>
</Pressable>
)
}
return (
<KeyboardAvoidingView style={styles.container} verticalOffset={64}>
<ErrorAlert error={error} setError={setError}/>
<View style={styles.searchContainer}>
<Feather name="search" size={18} color="#808080" style={styles.searchIcon}/>
<TextInput
style={styles.searchInput}
value={search}
defaultValue={search}
onChangeText={value => setSearch(value)}
placeholder="Search by name..."
placeholderTextColor="#808080"
returnKeyType="default"
spellCheck={true}
/>
{search ? (
<Pressable style={styles.searchClearButton} onPress={onPressClear}>
<Feather name="x" size={12} color="#eee"/>
</Pressable>
) : null}
</View>
{search ? results ? (
<FlatList
data={results}
extraData={sport}
renderItem={renderItem}
keyExtractor={(item, index) => item.key}
initialNumToRender={16}
onEndReached={onEndReached}
contentContainerStyle={styles.scrollContainer}
/>
) : null : (
<FlatList
data={SPORTS}
extraData={sport}
renderItem={renderItem}
keyExtractor={(item, index) => index.toString()}
initialNumToRender={16}
onEndReached={onEndReached}
contentContainerStyle={styles.scrollContainer}
/>
)}
</KeyboardAvoidingView>
)
}
export default CreateGame_Sport
Any and all suggestions are welcome! :)
How do I do the "see more" in react native web? My problem is on the onLayout and onTextLayout.
How do I determine to show the "see more" if its too long?
const ReadMoreText = () => {
const [textShown, setTextShown] = useState(false) //To show ur remaining Text
const [lengthMore, setLengthMore] = useState(false) //to show the "Read more & Less Line"
const toggleNumberOfLines = () => {
//To toggle the show text or hide it
setTextShown(!textShown)
}
const onTextLayout = useCallback((e) => {
// setLengthMore(e.nativeEvent.lines.length >= 4) //to check the text is more than 4 lines or not
// console.log(e.nativeEvent);
}, [])
return (
<View style={styles.mainContainer}>
<Text
onLayout={onTextLayout}
numberOfLines={textShown ? undefined : 4}
>
SAMPLE TEXT HERE...
</Text>
{lengthMore ? (
<Text
onPress={toggleNumberOfLines}
>
{textShown ? 'Read less...' : 'Read more...'}
</Text>
) : null}
</View>
)
}
I spent a long time looking into this and my solution was to implement a really simple component (below) which just limits the lines and allows you to show more. Maybe this is enough for you.
If not you could create a ref and use measureInWindow to get the measurement of the text container. ref.measureInWindow((x, y, width, height) => {})
import * as React from 'react'
import { Text } from 'react-native'
export default function ReadMore({ children, numLines = 4, style }) {
const [lines, setLines] = React.useState(numLines)
return (
<>
<Text numberOfLines={lines} style={style}>
{children}
</Text>
{lines === 0 ? (
<Text onPress={() => setLines(numLines)} style={{fontWeight:'bold'}}>
Read Less
</Text>
) : (
<Text onPress={() => setLines(0)} style={{fontWeight:'bold'}}>
Read More
</Text>
)}
</>
)
}
You can simply define a line height and then divide that by the total height of the text to get the number of lines. Here's how I did it.
import { useState, useCallback } from 'react'
import { Platform, LayoutChangeEvent } from 'react-native'
const LINE_HEIGHT = 30
const [numOfLines, setNumOfLines] = useState(0)
const [isInitialLayoutLoaded, setInitialLayoutLoaded] = useState(false)
const onLayout = useCallback((e: LayoutChangeEvent) => {
if (!isInitialLayoutLoaded && Platform.OS === 'web') {
setNumOfLines(e.nativeEvent.layout.height / LINE_HEIGHT)
setInitialLayoutLoaded(true)
}
},
[isInitialLayoutLoaded],
)
Then simply use it like:
<Text onLayout={onLayout}>A very long piece of text</Text>
#Joseph
just update your code
import * as React from 'react'
import { Text } from 'react-native'
export default function ReadMore({ children, numLines = 4, style }) {
const [lines, setLines] = React.useState(numLines)
const [showButton, setShowButton] = React.useState(false)
const onTextLayout = (e) => {
if(e.nativeEvent.lines.length > numLines){
setShowButton(true)
}
}
return (
<>
<Text onTextLayout={onTextLayout} numberOfLines={lines} style={style}>
{children}
</Text>
{showButton && <>
{lines === 0 ? (
<Text onPress={() => setLines(numLines)} style={{fontWeight:'bold'}}>
Read Less
</Text>
) : (
<Text onPress={() => setLines(0)} style={{fontWeight:'bold'}}>
Read More
</Text>
)}</>}
</>
)}
I am having trouble updatingĀ flatListĀ on the first screen when some item from theĀ flatlistĀ is deleted or added on the second screen to theĀ flatlist. MyĀ flatlistĀ is of bands and when I click on the individual name I see the details like band members, songs, albums, etc. I've two screens currently, the home screen with a list and add or delete screen, where items on the list can be customized. This is what I have so far, but I can't manage to update the list on the main page when something is removed on the second page from the list.
import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View, FlatList, TouchableOpacity, TouchableHighlight, Button, Alert, Modal, TextInput, ScrollView, SafeAreaView } from 'react-native';
import 'react-native-gesture-handler';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
function UselessTextInput(props) {
return (
<TextInput
{...props}
style={{ height: 30, borderWidth: 1, padding: 6, paddingTop: 10, margin: 5, color: '#FFFCD3', borderColor: '#A5C9FA', }}
editable
maxLength={30}
/>
); t
}
const musiciansArray = [
{ id: 1, key: 'A', value: 'Pink Floyd', members: 4, songs: 165 },
{ id: 2, key: 'B', value: 'Deep Purple', members: 5, songs: 70 },
{ id: 3, key: 'C', value: 'AC/DC', members: 5, songs: 80 },[![enter image description here][1]][1]
];
function HomeScreen({ navigation, route }) {
const [listItems, setListItems] = useState(musiciansArray);
const [store1, setStore1] = useState("");
const [idDeleteInput, setIdDeleteInput] = useState();
//const [exampleArray, setExampleArray] = useState(musiciansArray);
const ItemView = ({ item }) => {
return (
<View>
<Text
style={styles.item}
onPress={() => getItem(item)}>
{item.value}
</Text>
</View>
);
};
const ItemSeparatorView = () => {
return (
<View style={styles.fList} />
);
};
const EmptyListMessage = ({ item }) => {
return (
<Text
style={styles.emptyListStyle}
onPress={() => getItem(item)}>
Empty list found.
</Text>
);
};
const getItem = (item) => {
alert(' id: ' + item.id + '\n' + ' key: ' + item.key + '\n' + ' Band Name: ' + item.value + '\n' + ' Members: ' + item.members + '\n' + ' Songs: ' + item.songs)
};
useEffect(() => {
if (route.params?.post) {
setListItems(JSON.parse(route.params?.post).nameOfBand);
}
}, [route.params?.post]);
return (
<View style={styles.container}>
<View >
<View>
<Text style={styles.text1}>Bands</Text>
<FlatList
data={listItems}
ItemSeparatorComponent={ItemSeparatorView}
renderItem={ItemView}
keyExtractor={item => item.id}
ListEmptyComponent={EmptyListMessage} />
</View>
<View style={styles.fixToText}>
<TouchableHighlight style={styles.button2}
onPress={() => navigation.navigate('Input')}
activeOpacity={0.6}
underlayColor='red'
>
<Text style={styles.textButton}>Add or Delete</Text>
</TouchableHighlight>
</View>
</View>
</View>
);
}
function InputScreen({ navigation,route }) {
const [listItems, setListItems] = useState(musiciansArray);
const [nameOfBand, setNameOfBand] = useState('');
const [keyOfBand, setkeyOfBand] = useState('');
const [memInput2, setMemInput2] = useState('');
const [songInput2, setSongInput2] = useState('');
const [idDeleteInput, setIdDeleteInput] = useState();
const [idDeleteInput2, setIdDeleteInput2] = useState();
const [exampleArray, setExampleArray] = useState(musiciansArray);
const delItem = () => {
navigation.navigate('InputScreen', { post: JSON.stringify({ text: idDeleteInput2 }) });
if (idDeleteInput2 > musiciansArray.length || idDeleteInput2 === "" || isNaN(idDeleteInput2)) {
Alert.alert('No such id is present.');
} else if (exampleArray.length === 0) {
Alert.alert('Nothing can be deleted, empty list found.');
}
else {
Alert.alert("Item with id " + idDeleteInput2 + " sucessfully deleted.");
const filteredArray = exampleArray.filter(item => item.id != idDeleteInput2);
setExampleArray(filteredArray);
}
}
const alertAdd = () => {
navigation.navigate('InputScreen', { post: JSON.stringify({ text: nameOfBand, text: keyOfBand , text: memInput2 ,text: songInput2 }) });
if (nameOfBand == "" || keyOfBand == "" || memInput2 == "" || songInput2 == "") {
Alert.alert("No new item has been added, as atleast a field is empty.");
} else {
var newArray = [...exampleArray, { id: exampleArray.length + 1, key: keyOfBand, value: nameOfBand, members: memInput2, songs: songInput2 }];
setExampleArray(newArray);
Alert.alert("Item " + nameOfBand + " added successfully.");
}
};
return (
<View style={styles.container}>
<View>
<Text style={styles.text3}>Add</Text>
<Text style={styles.text4}>Band Name:</Text>
<UselessTextInput
multiline
numberOfLines={4}
value={nameOfBand}
onChangeText={itemText => setNameOfBand(itemText)}
/>
<Text style={styles.text4}>Key e.g. A, B, C:</Text>
<UselessTextInput
multiline
numberOfLines={4}
value={keyOfBand}
onChangeText={itemText => setkeyOfBand(itemText)}
/>
<Text style={styles.text4}>No. of Members:</Text>
<UselessTextInput
multiline
numberOfLines={4}
value={memInput2}
onChangeText={itemText => setMemInput2(itemText)}
/>
<Text style={styles.text4}>No. of Songs:</Text>
<UselessTextInput
multiline
numberOfLines={4}
value={songInput2}
onChangeText={itemText => setSongInput2(itemText)}
/>
</View>
<View style={styles.fixToText}>
{/* <TouchableOpacity onPress={alertAdd}
style={styles.button2}>
<Text style={styles.textButton}>Press To Add</Text>
</TouchableOpacity> */}
<TouchableOpacity
// onPress={alertAdd}
onPress={alertAdd}
// Pass params back to home screen
style={styles.button2}>
<Text style={styles.textButton}>Press To Add</Text>
</TouchableOpacity>
</View>
<View>
<Text style={styles.text3}>Delete</Text>
<Text style={styles.text4}>Id to delete:</Text>
<UselessTextInput
multiline
numberOfLines={4}
value={idDeleteInput2}
onChangeText={delID => setIdDeleteInput2(delID)} />
</View>
<View style={styles.fixToText2}>
<TouchableOpacity onPress={delItem}
style={styles.button3}>
<Text style={styles.textButton}>Press To Del</Text>
</TouchableOpacity>
</View>
</View>
);
}
const Stack = createStackNavigator();
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Input" component={InputScreen} />
</Stack.Navigator>
</NavigationContainer>
);
};
export default App;
This is what my app looks like right now:
I know this is a lot of code, but I have mentioned the gist of the concept here, I am probably missing something here regarding navigation, as I am pretty new to that concept. Thanks in advance!
The reason for screen not being updated is when you are navigating back to the screen, the screen is not re rendered as it is already rendered. The changes made on the second screen doesn't re renders the previous screen. In case to achieve that, if you are using react navigation then there is a option to add Event Listener for screen focus, you can use that event to update your screen.
See: https://reactnavigation.org/docs/navigation-events/
the navigationOptions code like that.
static navigationOptions = ({navigation})=>({
tabBarLabel:'ę„ē',
headerTitle:navigation.state.params.title,
tabBarIcon: ({ tintColor,focused }) => (
<Image style={SKIN.tabImage} source={focused?AppImages.MyPost.lookchoose:AppImages.MyPost.look}/>
),
});
this is my Tab componet,how I can get tabBarLabel and tabBarIcon?
export default class Tab extends Component {
renderItem = (route, index) => {
const {
navigation,
jumpToIndex,
} = this.props;
const focused = index === navigation.state.index;
const color = focused ? this.props.activeTintColor : this.props.inactiveTintColor;
return (
<TouchableOpacity
key={index}
style={styles.tabItem}
onPress={() => jumpToIndex(index)}
>
<View
style={styles.tabItem}>
{this.props.renderIcon(color,focused)}
<Text style={{ color }}>{this.props.getLabel()}</Text>
</View>
</TouchableOpacity>
);
};
render(){
console.log('Tab this.props',this.props);
const {navigation,} = this.props;
const {routes,} = navigation.state;
return (
<View style={styles.tab}>
{routes && routes.map(this.renderItem)}
</View>
);
}
}
I custom Tab,now I want use that but some bug show me.
like that,
imagebug
please help me...
try updating the render method with this code:
render(){
console.log('Tab this.props',this.props);
const {navigation,} = this.props;
const {routes,} = navigation.state;
return (
<View style={styles.tab}>
//pass down the route and the index to the renderItem function
{routes && routes.map((route,index) => this.renderItem(route, index) )}
</View>
);
renderItem = (route, index) => {
const {
navigation,
jumpToIndex,
} = this.props;
const focused = index === navigation.state.index;
const color = focused ? this.props.activeTintColor : this.props.inactiveTintColor;
let TabScene = {
focused:focused,
route:route,
tintColor:color
};
return (
<TouchableOpacity
key={route.key}
style={styles.tabItem}
onPress={() => jumpToIndex(index)}
>
<View
style={styles.tabItem}>
{this.props.renderIcon(TabScene)}
<Text style={{ color }}>{this.props.getLabel(TabScene)}</Text>
</View>
</TouchableOpacity>
);
};