Unable to access state variable declared inside useEffect - react-native

I have a react native screen where I am calling an API on useEffect and setting two state variables using hooks, i.e. cityList, filteredCityList. filteredCityList is bind to autocomplete dropdown. On change of this dropdown, a function called filterCity gets called. I am unable to access the cityList inside this function.
Please advise what am I missing here.
import React, {useCallback, useEffect, useState} from 'react';
import {View, StyleSheet} from 'react-native';
import {Button, Card, Portal, Text, Modal, FAB} from 'react-native-paper';
import {AutocompleteDropdown} from 'react-native-autocomplete-dropdown';
import Icon from 'react-native-vector-icons/Feather';
import {getCities} from '../API/api';
import {useFocusEffect} from '#react-navigation/native';
const AddHospital = () => {
const [selectedCity, setSelectedCity] = useState(null);
const [cityListFiltered, setCityListFiltered] = useState([]);
const [cityList, setCityList] = useState([]);
const [cityDDLoading, setCityDDLoading] = useState(false);
const [selectedCityError, setSelectedCityError] = useState(false);
console.log('reloading');
const filterCity = q => {
console.log(q);
console.log('City List', cityList);
};
const loadCities = async () => {
setCityDDLoading(true);
var citiesResponse = await getCities();
if (citiesResponse.responseData) {
var cities = citiesResponse.responseData.records.map(item => ({
id: item.id,
title: item.cityname,
}));
console.log('setting cities', cities);
setCityList(cities);
// setCityListFiltered(cities);
// setCityDDLoading(false);
} else {
console.log('Failed to load cities');
}
};
useEffect(() => {
loadCities();
}, []);
return (
<View>
<Card style={styles.container}>
<Card.Title title="Select Hospital"></Card.Title>
<Card.Content>
<AutocompleteDropdown
clearOnFocus={false}
closeOnBlur={true}
closeOnSubmit={false}
onSelectItem={item => {
item && setSelectedCity(item);
}}
dataSet={cityListFiltered}
debounce={600}
onChangeText={text => filterCity(text)}
suggestionsListMaxHeight={120}
loading={cityDDLoading}
useFilter={false} // prevent rerender twice
textInputProps={{
placeholder: 'Select City',
autoCorrect: false,
autoCapitalize: 'none',
style: {
// borderRadius: 25,
backgroundColor: '#f6f6f6',
color: 'black',
paddingLeft: 18,
borderWidth: 1,
borderColor: selectedCityError ? 'red' : 'gray',
borderStyle: 'solid',
},
placeholderTextColor: 'black',
}}
rightButtonsContainerStyle={{
// borderRadius: 25,
right: 8,
height: 30,
top: 10,
alignSelfs: 'center',
backgroundColor: '#f6f6f6',
// backgroundColor: "#383b42"
}}
inputContainerStyle={{
backgroundColor: 'transparent',
zIndex: 0,
}}
suggestionsListContainerStyle={
{
//backgroundColor: "#383b42"
//color: '#fff'
// zIndex: 1000
}
}
containerStyle={{
flexGrow: 1,
flexShrink: 1,
marginBottom: 100,
marginTop: 10,
zIndex: 0,
}}
renderItem={(item, text) => (
<Text style={{color: 'black', padding: 15}}>{item.title}</Text>
)}
ChevronIconComponent={<Icon name="chevron-down" size={24} />}
ClearIconComponent={<Icon name="x" size={18} />}
inputHeight={50}
showChevron={true}
showClear={true}
// style={styles.autoComplete}
/>
</Card.Content>
</Card>
<Text>{cityList.length}</Text>
</View>
);
};
export default AddHospital;
const styles = StyleSheet.create({
container: {
flex: 0,
margin: 10,
},
});

Related

React Native Flatlist onReachEnd (load more item) with bottom tabs navbar after scroll flatlist till bottom it's like re render flatlist component

I'm trying to make load more content on flatlist with bottom navbar
but after I try to scroll til bottom of page
the result is : new data show up but, idk why the flatlist like re render and move to top page again
expected result : new data show up and screen not move to the top page again
note : if i try without bottom navbar (only flatlist) it works~
btw i'm using react native functional component
dependency package
"#react-navigation/bottom-tabs": "^6.0.7",
"react": "^17.0.2",
"react-native": "0.65.1",
import React, {Component, useEffect, useState, useCallback} from 'react';
import {
Text,
View,
StyleSheet,
Dimensions,
ScrollView,
SafeAreaView,
FlatList,
TouchableHighlight,
ActivityIndicator,
} from 'react-native';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
import {Avatar, Card, Paragraph} from 'react-native-paper';
import {TouchableOpacity, RefreshControl} from 'react-native-gesture-handler';
import {
IconShipTruck,
IconShipTruckPending,
IconShipTruckPendingActive,
IconShipTruckGoing,
IconShipTruckGoingActive,
IconShipTruckHistory,
IconShipTruckHistoryActive,
} from '../../assets';
import GLOBAL_STYLE from '../../assets/styles/global_style';
import {List} from 'react-native-paper';
import {_getStorageValue, STATUS_PENDING} from '../../utils/constant';
import axios from 'axios';
import Moment from 'moment';
const Shipments = ({navigation}) => {
const Tab = createBottomTabNavigator();
const [isFetching, setFetching] = useState(false);
const [dataPending, setDataPending] = useState([]);
const [dataOnGoing, setDataOnGoing] = useState();
const [dataHistory, setDataHistory] = useState();
// paging
const [loadMore, setLoadMore] = useState(true);
const [fetchLoad, setFetchLoad] = useState(false);
const [pagePending, setPagePending] = useState(1);
const [limitPending, setLimitPending] = useState(6);
const [endReachMomentum, setEndReachMomentum] = useState(true);
useEffect(() => {
var page = 1;
getPending('refresh', page); // refresh or initial data
}, []);
const handleLoadMore = useCallback(() => {
if (loadMore == true) {
// load more = true jika current page ada datanya
setFetchLoad(true);
var page = pagePending + 1;
setPagePending(page);
getPending('loadmore', page);
}
}, [pagePending]);
const handleEndReach = ({distanceFromEnd}) => {
if (!endReachMomentum) {
handleLoadMore();
setEndReachMomentum(true);
}
};
const handleRefresh = useCallback(() => {
var page = 1;
setPagePending(page);
setLoadMore(true);
setFetching(true);
getPending('refresh', page);
}, []);
async function getPending(type, page) {
// initial data
var data = [];
var configsTemp = await _getStorageValue('#configs');
if (configsTemp !== null) {
var configs = JSON.parse(configsTemp);
var baseUrl = configs.value;
var authTemp = await _getStorageValue('#authorization');
if (authTemp !== null) {
var authorization = JSON.parse(authTemp);
var accessToken = authorization.access_token;
var tokenType = authorization.token_type;
var username = authorization.user_data.username;
var status = STATUS_PENDING;
// req data pending
var epPending = `${baseUrl}/shipment/get_ship_loads/${status}/${username}?p_current_pages=${page}&p_limit=${limitPending}`;
var optionsPending = {
headers: {
accept: 'application/json',
Authorization: `${tokenType} ${accessToken}`,
},
};
axios
.get(epPending, optionsPending)
.then(res => {
if (res.data.status == 'SUCCESS') {
data = res.data.data;
if (type == 'refresh') {
setDataPending(data);
setLoadMore(true);
} else if (type == 'loadmore') {
if (data.length > 0 && data.length < limitPending) {
// kondisi data kurang dari limit
setPagePending(page);
setLoadMore(false);
setDataPending(prevData => [...prevData, ...data]);
} else if (data.length == 0) {
// kondisi data kosong
setPagePending(page - 1);
setLoadMore(false);
} else if (data.length == limitPending) {
// kondisi data terfulfill
setPagePending(page);
setDataPending(prevData => [...prevData, ...data]);
}
}
}
setFetchLoad(false);
})
.catch(err => {
console.log(err);
setFetchLoad(false);
});
}
}
setFetching(false);
}
const Item = ({data, moveTo}) => (
<List.Section>
<List.Accordion
theme={{colors: {primary: 'black'}}}
titleStyle={[styles.divLoadNumber]}
title={
<Text style={GLOBAL_STYLE.poppinsMedium}>
{'[' +
data.trans_type_desc +
'] ' +
data.site_initial_dc +
' - Load number ' +
data.load_number}
</Text>
}
titleNumberOfLines={1}
descriptionStyle={styles.divLoadNumberDetail}
descriptionNumberOfLines={5}
description={
<>
<Paragraph style={GLOBAL_STYLE.poppinsRegular}>
Total Container : {data.total_containers} {`\t\t`} Total Qty :{' '}
{data.total_items_qty}
</Paragraph>
{'\n'}
<Paragraph style={GLOBAL_STYLE.poppinsRegular}>
Processing Date :{' '}
{Moment(data.load_process_date).format('DD MMM YYYY HH:mm')}
</Paragraph>
</>
}>
{data.shipmentList.map((sl, index, navigate) => {
return (
<TouchableOpacity
style={{backgroundColor: '#f5f5f5'}}
key={sl.id}
disabled={index == 0 && sl.flag == 0 ? false : true}
onPress={() => {
navigation.navigate(`${moveTo}`, {
loadNumber: data.load_number,
siteDc: data.site_code_dc,
dc: data.site_initial_dc,
dataHeader: sl,
});
}}>
<List.Item
style={{paddingBottom: 0, paddingTop: 0}}
titleStyle={[
GLOBAL_STYLE.poppinsRegular,
styles.divPO,
{backgroundColor: '#e0e5e5'},
]}
titleNumberOfLines={2}
title={
<View style={{flex: 1, flexDirection: 'row'}}>
<View style={styles.divPODetailIndex}>
<Text style={GLOBAL_STYLE.poppinsMedium}>
{index + 1}
</Text>
</View>
<View style={{flex: 3}}>
<Text style={GLOBAL_STYLE.poppinsMedium}>
{' '}
PO number : {sl.po_no}
</Text>
</View>
</View>
}
descriptionStyle={styles.descriptionAccordionChild}
descriptionNumberOfLines={4}
description={
<>
<Paragraph style={GLOBAL_STYLE.poppinsRegular}>
Booking Number : {sl.transaction_no}
</Paragraph>
{'\n'}
<Paragraph style={GLOBAL_STYLE.poppinsRegular}>
Address :{' '}
</Paragraph>
{'\n'}
<Paragraph style={GLOBAL_STYLE.poppinsRegular}>
{sl.cust_address +
', ' +
sl.cust_kecamatan +
', ' +
sl.cust_kelurahan +
', ' +
sl.cust_city}
</Paragraph>
</>
}
/>
</TouchableOpacity>
);
})}
</List.Accordion>
</List.Section>
);
const renderItem = ({item}) => <Item data={item} moveTo={'OrderDetails'} />;
const pendingFooter = useCallback(() => {
if (loadMore == true && fetchLoad == true) {
return (
<View>
<ActivityIndicator size="large" />
</View>
);
} else {
return true;
}
}, [loadMore, fetchLoad]);
const shipmentList = useCallback(() => {
return (
<SafeAreaView style={styles.container}>
<Text>
{pagePending} : {loadMore == true ? 1 : 0}
</Text>
<FlatList
data={dataPending}
renderItem={renderItem}
keyExtractor={item => item.id}
refreshing={isFetching}
onRefresh={handleRefresh}
onEndReached={handleEndReach}
onEndReachedThreshold={0.000001}
onMomentumScrollBegin={() => {
setEndReachMomentum(false);
}}
ListFooterComponent={pendingFooter}
ListFooterComponentStyle={{marginBottom: 20}}
initialNumToRender={limitPending}
maxToRenderPerBatch={limitPending}
/>
</SafeAreaView>
);
});
return (
<Tab.Navigator
screenOptions={{
tabBarStyle: {position: 'absolute', height: 60},
tabBarLabelStyle: [GLOBAL_STYLE.poppinsRegular, styles.tabBarLabel],
}}>
<Tab.Screen
name="Awaiting to Delivery"
component={shipmentList}
options={{
tabBarLabel: 'Pending',
tabBarIcon: ({focused}) => {
const flag = focused;
if (flag) {
return <IconShipTruckPendingActive />;
} else {
return <IconShipTruckPending />;
}
},
headerTitleStyle: [
GLOBAL_STYLE.poppinsSemibold,
GLOBAL_STYLE.headerTitleNavbar,
],
}}
/>
</Tab.Navigator>
);
};
export default Shipments;
const windowWidth = Dimensions.get('window').width;
const windowHeight = Dimensions.get('window').height;
const styles = StyleSheet.create({
container: {
flex: 1,
},
card: {
height: 140,
width: windowWidth * 0.96,
borderWidth: 0.5,
borderColor: 'black',
marginTop: 10,
marginBottom: 5,
borderRadius: 10,
shadowColor: '#000000',
shadowOpacity: 0.8,
shadowRadius: 2,
color: 'blue',
shadowOffset: {
height: 1,
width: 0,
},
},
cardTitle: {
borderWidth: 0.5,
borderColor: 'blue',
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
backgroundColor: 'lightblue',
},
cardTitleOngoing: {
borderWidth: 0.5,
borderColor: 'blue',
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
backgroundColor: 'lightgreen',
},
tabBarLabel: {
fontSize: 12,
},
divPODetailIndex: {
flex: 3,
backgroundColor: 'white',
width: 30,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 5,
},
divLoadNumber: {
backgroundColor: '#a5f5ef',
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
borderColor: 'gray',
borderWidth: 0.5,
marginTop: -13.5,
fontSize: 14,
paddingVertical: 10,
paddingHorizontal: 20,
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
},
divLoadNumberDetail: {
backgroundColor: 'white',
borderBottomLeftRadius: 10,
borderBottomRightRadius: 10,
borderColor: 'gray',
borderLeftWidth: 0.5,
borderRightWidth: 0.5,
borderBottomWidth: 0.5,
marginBottom: -13.5,
paddingVertical: 10,
paddingHorizontal: 20,
},
divPO: {
marginLeft: 30,
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
paddingVertical: 10,
paddingHorizontal: 20,
borderColor: 'gray',
borderWidth: 0.5,
},
descriptionAccordionChild: {
marginLeft: 30,
backgroundColor: 'white',
borderBottomLeftRadius: 10,
borderBottomRightRadius: 10,
paddingVertical: 10,
paddingHorizontal: 20,
borderColor: 'gray',
borderLeftWidth: 0.5,
borderRightWidth: 0.5,
borderBottomWidth: 0.5,
},
});
No Bottom Navbar
With Bottom Navbar
OKEY GUYS I Found the answerrrr finally
create new file for flatlist only
on tabscreen component target to the new file
<Tab.Screen
name="Awaiting to Delivery"
component={Pendings} => new file that flatlist only

Too Many renders. React Limits the number of renders to prevent infinite loop

am getting an error while running my react native app in expo , my error is Too many renders react limits the number of renders to prevent infinite loop, don't know where am wrong , please try to fix my error. if you have any question please free feel to ask ant time.
Home.js
This is the home.js file where in wrote my all code including css.
import React, { useEffect, useState } from 'react'
import { Text, View, FlatList, StyleSheet, ScrollView, Image } from 'react-native';
import { Avatar } from 'react-native-elements';
import { Searchbar, shadow, Modal, Provider, Portal } from 'react-native-paper';
import { AntDesign } from '#expo/vector-icons';
export default function Home() {
const [searchquery, setSearchquery] = React.useState();
const [visible, setVisible] = React.useState(false);
const showModal = setVisible(true);
const hideModal = setVisible(false);
const containerStyle = { backgroundColor: 'white', padding: 20 };
const [users, setUser] = useState([
{
id: 1,
name: "Ashish Nirvikar"
},
{
id: 2,
name: "Drew Macntyre"
},
{
id: 3,
name: "Jonh Cena"
},
{
id: 4,
name: "Rock Samoa"
},
{
id: 5,
name: "Boby Lashely"
},
])
return (
<View >
<Searchbar
placeholder="Search Contacts"
onChangeText={(query) => setSearchquery(query)}
value={searchquery}
style={{ marginTop: 30, marginHorizontal: 10 }}
/>
<ScrollView>
{
users.map((item, index) => {
return (
<View key={index}>
<Text style={styles.names}>{item.name}</Text>
</View>
)
})
}
</ScrollView>
<Provider>
<Portal>
<Modal visible={visible} onDismiss={hideModal} contentContainerStyle={containerStyle}>
<Text>Example Modal. Click outside this area to dismiss.</Text>
</Modal>
</Portal>
<AntDesign name="plus" size={34} color="black" style={styles.plus} onPress={showModal} />
</Provider>
</View>
);
}
const styles = StyleSheet.create({
customText: {
padding: 10,
marginTop: 20,
textAlign: 'center',
backgroundColor: 'lightgray',
fontWeight: 'bold',
fontSize: 20
},
plus: {
fontSize: 50,
position: 'absolute',
top: 680,
right: 40,
backgroundColor: 'pink',
borderRadius: 15,
borderWidth: 0.5,
padding: 5,
},
names: {
padding: 15,
fontSize: 25,
fontWeight: 'bold',
backgroundColor: 'lightgray',
marginTop: 10,
borderRadius: 20,
color: 'black'
}
});
The showModal and hideModal are functions, define it as a function.
const showModal = () => setVisible(true);
const hideModal = () => setVisible(false);

React Native Conditional style onFocus onBlur using Reusable Function Component

I have a reusable text input component using Native Base that I used on many screen, the goal is when text input on focus, the border changes color to #6852E1. When on blur, it changes to #8B8B8B.
The code below doesn't work like I want, or maybe there is something wrong with my code. How can I achieve that? Thanks
Here's the code
import React, { useState } from "react";
import { Dimensions } from "react-native";
import { Item, Input, Label, Icon } from "native-base";
import * as Font from "expo-font";
let borderColor;
// prettier-ignore
Font.loadAsync({
Calibre_Regular: require("../assets/fonts/Calibre-Regular.ttf"),
"Calibre_Regular": require("../assets/fonts/Calibre-Regular.ttf"),
});
const CustomTextInput = ({
value,
onChangeText,
label,
onSubmitEditing,
getRef,
onPress,
onPress2,
returnKeyType,
keyboardType,
editable,
secureTextEntry,
iconName,
iconName2,
whichStyle,
defaultValue,
}) => {
const { itemStyle1, itemStyle2, textInput, floatingLabel } = InputFieldStyles;
return (
<Item
floatingLabel
style={whichStyle ? itemStyle2 : itemStyle1}
onPress={onPress2}
>
<Icon style={{ marginLeft: 10, color: "#8B8B8B" }} name={iconName2} />
<Label style={floatingLabel}>{label}</Label>
<Input
onBlur={() => (borderColor = "#8B8B8B")}
onFocus={() => (borderColor = "#6852E1")}
style={textInput}
blurOnSubmit={false}
getRef={getRef}
value={value}
defaultValue={defaultValue}
editable={editable}
onChangeText={onChangeText}
onSubmitEditing={onSubmitEditing}
returnKeyType={returnKeyType}
keyboardType={keyboardType}
secureTextEntry={secureTextEntry}
/>
<Icon name={iconName} onPress={onPress} />
</Item>
);
};
const InputFieldStyles = {
textInput: {
padding: 10,
marginVertical: 10,
fontSize: 16,
color: "rgba(0, 0, 0, 0.87)",
fontFamily: "Calibre_Regular",
},
floatingLabel: {
marginLeft: 10,
marginTop: 8,
fontFamily: "Calibre_Regular",
},
itemStyle1: {
marginLeft: 0,
backgroundColor: "#FFF",
borderColor: borderColor,
// borderColor: "#6852E1",
// borderColor: "#8B8B8B",
borderBottomWidth: 3,
},
itemStyle2: {
marginLeft: 0,
backgroundColor: "#F6F7FC",
borderColor: borderColor,
borderBottomWidth: 3,
},
itemStyle3: {
marginLeft: 0,
backgroundColor: "#FFF",
borderColor: "#6852E1",
borderBottomWidth: 3,
},
};
export { CustomTextInput };
this is my code with the right answer for those who needs
import React, { useState } from "react";
import { Dimensions } from "react-native";
import { Item, Input, Label, Icon } from "native-base";
import * as Font from "expo-font";
// prettier-ignore
Font.loadAsync({
Calibre_Regular: require("../assets/fonts/Calibre-Regular.ttf"),
"Calibre_Regular": require("../assets/fonts/Calibre-Regular.ttf"),
});
const CustomTextInput = ({
value,
onChangeText,
label,
onSubmitEditing,
getRef,
onPress,
onPress2,
returnKeyType,
keyboardType,
editable,
secureTextEntry,
iconName,
iconName2,
whichStyle,
defaultValue,
}) => {
const { itemStyle1, itemStyle2, textInput, floatingLabel } = InputFieldStyles;
const [isFocused, setIsFocused] = useState(false);
return (
<Item
floatingLabel
style={whichStyle ? itemStyle2 : itemStyle1({ isFocused })}
onPress={onPress2}
>
<Icon style={{ marginLeft: 10, color: "#8B8B8B" }} name={iconName2} />
<Label style={floatingLabel}>{label}</Label>
<Input
onBlur={() => setIsFocused(false)}
onFocus={() => setIsFocused(true)}
style={textInput}
blurOnSubmit={false}
getRef={getRef}
value={value}
defaultValue={defaultValue}
editable={editable}
onChangeText={onChangeText}
onSubmitEditing={onSubmitEditing}
returnKeyType={returnKeyType}
keyboardType={keyboardType}
secureTextEntry={secureTextEntry}
/>
<Icon name={iconName} onPress={onPress} />
</Item>
);
};
const InputFieldStyles = {
textInput: {
padding: 10,
marginVertical: 10,
fontSize: 16,
color: "rgba(0, 0, 0, 0.87)",
fontFamily: "Calibre_Regular",
},
floatingLabel: {
marginLeft: 10,
marginTop: 8,
fontFamily: "Calibre_Regular",
},
itemStyle1: ({ isFocused }) => ({
marginLeft: 0,
backgroundColor: "#FFF",
borderColor: isFocused ? "#6852E1" : "#8B8B8B",
borderBottomWidth: 3,
}),
itemStyle2: {
marginLeft: 0,
backgroundColor: "#F6F7FC",
borderBottomWidth: 3,
},
itemStyle3: {
marginLeft: 0,
backgroundColor: "#FFF",
borderColor: "#6852E1",
borderBottomWidth: 3,
},
};
export { CustomTextInput };
Try this:
const CustomTextInput = () => {
const [isFocused, setIsFocused] = setState(false);
return (
/** ... */
<Item style={itemStyle({ isFocused })}>
>
<Input
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
/>
</Item>
/** ... */
);
};
itemStyle: ({ isFocused }) => ({
borderColor: isFocused ? 'focused-color' : 'unfocused-color'
}),

how to get current flat list item data in reactnative using react-native-swipe-list-view

I'm not getting how to get the current item object of a flat list
I used react-native-swipeout and react-native-swipe-list-view and in both examples I stuck.
And on google I found very big answers. Which are not pointing only the particular issue which confused me a lot.
the below is the deleted function when I used react-native-swipeout plugin
const swipeSettings = {
left: [
{
text: 'Delete',
onPress: () => {
console.log('-----delete-----');
},
type: 'delete',
},
}
All I need is to get the current item object data like below inside onpress() when i tapped the delete button .
{
id: 1,
prodName : "abcdefg",
}
That's all, I came from native script background and in that framework I never faced such issue. Because the documentation was crystal clear. But here In react native everything seems to be complicated for me.
Kindly any one help me.
<FlatList
data={data}
keyExtractor={(item) => item.id}
renderItem={({item, index}) => (
<Swipeout {...swipeSettings}>
<View style={styles.listView}>
<Text style={styles.listViewText}>{item.prodName}</Text>
</View>
</Swipeout>
)}
/>
entire page
import React, {useState} from 'react';
import {View} from 'react-native-animatable';
import {
TextInput,
TouchableOpacity,
FlatList,
} from 'react-native-gesture-handler';
import Icon from 'react-native-vector-icons/FontAwesome';
import {StyleSheet, Pressable, Text, Button} from 'react-native';
import * as Animatable from 'react-native-animatable';
import Swipeout from 'react-native-swipeout';
import ButtonPressable from '../../components/ButtonPressable';
var sqlite_wrapper = require('./sqliteWrapper');
const DATA = [
{
prodName: 'Added data will look like this',
},
];
const swipeSettings = {
style: {
marginBottom: 10,
},
autoClose: false,
backgroundColor: 'transparent',
close: false,
disabled: false,
onClose: (sectionID, rowId, direction) => {
console.log('---onclose--');
},
onOpen: (sectionID, rowId, direction) => {
console.log('---onopen--');
},
right: [
{
backgroundColor: 'dodgerblue',
color: 'white',
text: 'Edit',
onPress: () => {
console.log('-----edit-----');
},
},
],
left: [
{
backgroundColor: 'red',
color: 'white',
text: 'Delete',
onPress: () => {
console.log('-----delete-----');
sqlite_wrapper.deleteById
},
type: 'delete',
// component : (<ButtonPressable text="delete" />)
},
],
// buttonWidth: 100,
};
const AddProductList = ({route, navigation}) => {
const {navData} = route.params;
const [prodName, setProdName] = useState('');
var [data, setData] = useState(DATA);
return (
<View style={styles.container}>
<Animatable.View
animation="bounceIn"
duration={1000}
style={styles.inputFieldView}>
<TextInput
style={styles.textInput}
onChangeText={(value) => setProdName(value)}
placeholder="Add the Product"
defaultValue={prodName}
/>
<TouchableOpacity
style={styles.addView}
onPress={() => {
sqlite_wrapper
.insert({prodName: prodName}, sqlite_wrapper.collection_product)
.then((result) => {
console.log('---result---');
console.log(result);
if (result.rowsAffected) {
fetchAllData();
}
});
function fetchAllData() {
sqlite_wrapper
.readAll(sqlite_wrapper.collection_product)
.then((resultData) => {
console.log('---resultData---');
console.log(resultData);
setData(resultData);
setProdName('');
});
}
// without sql this is how to update the state having a array
// const updatedArray = [...data];
// updatedArray.push({prodName: prodName});
// setData(updatedArray);
// setProdName('');
}}>
<Icon name="plus" size={16} style={styles.add} color="white" />
</TouchableOpacity>
</Animatable.View>
<Animatable.View
animation="bounceInLeft"
duration={1500}
style={{flex: 1}}>
<FlatList
data={data}
keyExtractor={(item) => item.id}
renderItem={({item, index}) => (
<Swipeout {...swipeSettings}>
<View style={styles.listView}>
<Text style={styles.listViewText}>{item.prodName}</Text>
</View>
</Swipeout>
)}
/>
</Animatable.View>
</View>
);
};
var styles = StyleSheet.create({
container: {
flex: 1,
},
inputFieldView: {
flexDirection: 'row',
alignItems: 'center',
alignSelf: 'stretch',
margin: 10,
},
textInput: {
flex: 1,
backgroundColor: '#b2ebf2',
borderTopLeftRadius: 7,
borderBottomLeftRadius: 7,
fontSize: 16,
},
addView: {
backgroundColor: '#0f4c75',
alignSelf: 'stretch',
alignItems: 'center',
justifyContent: 'center',
borderTopEndRadius: 7,
borderBottomEndRadius: 7,
padding: 9,
},
add: {
padding: 7,
},
listView: {
padding: 20,
backgroundColor: 'green',
margin: 0,
borderRadius: 0,
},
listViewText: {
color: 'white',
},
});
export default AddProductList;
So if I get you right you have one generic swipe setting that you want to adjust to each element in the list.
Try changing the renderItem of the Flatlist like this and let me know how it worked for you:
<FlatList
data={data}
keyExtractor={(item) => item.id}
renderItem={({ item, index }) => {
let right = [...swipeSettings.right]; <---- ADDED
let left = [...swipeSettings.left]; <---- ADDED
right[0].onPress = () => console.log('edit', item.prodName); <---- ADDED
left[0].onPress = () => console.log('delete', item.prodName); <---- ADDED
<Swipeout {...swipeSettings} {...{ right, left}} > <---- CHANGED
<View style={styles.listView}>
<Text style={styles.listViewText}>{item.prodName}</Text>
</View>
</Swipeout>
}}
/>
So what I have done here is sending the generic swipe settings to each instance of Swipeout but changed their "Left" and "Right" in order to overwrite their "onPress" function and adjust it to the rendered item.
I know it is hard to understand it like this and it's probably not the best explanation but I hope it will help you somehow.
EDIT
import React, { useState } from 'react';
import { View } from 'react-native-animatable';
import {
TextInput,
TouchableOpacity,
FlatList,
} from 'react-native-gesture-handler';
import Icon from 'react-native-vector-icons/FontAwesome';
import { StyleSheet, Pressable, Text, Button } from 'react-native';
import * as Animatable from 'react-native-animatable';
import Swipeout from 'react-native-swipeout';
import ButtonPressable from '../../components/ButtonPressable';
var sqlite_wrapper = require('./sqliteWrapper');
const DATA = [
{
prodName: 'Added data will look like this',
},
];
const AddProductList = ({ route, navigation }) => {
const { navData } = route.params;
const [prodName, setProdName] = useState('');
var [data, setData] = useState(DATA);
const renderItem = ({ item, index }) => {
const swipeSettings = {
style: {
marginBottom: 10,
},
autoClose: false,
backgroundColor: 'transparent',
close: false,
disabled: false,
onClose: (sectionID, rowId, direction) => {
console.log('---onclose--');
},
onOpen: (sectionID, rowId, direction) => {
console.log('---onopen--');
},
right: [
{
backgroundColor: 'dodgerblue',
color: 'white',
text: 'Edit',
onPress: () => console.log('-----edit-----', item.prodName)
},
],
left: [
{
backgroundColor: 'red',
color: 'white',
text: 'Delete',
onPress: () => {
console.log('-----delete-----', item.prodName);
sqlite_wrapper.deleteById
},
type: 'delete',
// component : (<ButtonPressable text="delete" />)
},
],
// buttonWidth: 100,
};
return (
<Swipeout {...swipeSettings}>
<View style={styles.listView}>
<Text style={styles.listViewText}>{item.prodName}</Text>
</View>
</Swipeout>
)
}
return (
<View style={styles.container}>
<Animatable.View
animation="bounceIn"
duration={1000}
style={styles.inputFieldView}>
<TextInput
style={styles.textInput}
onChangeText={(value) => setProdName(value)}
placeholder="Add the Product"
defaultValue={prodName}
/>
<TouchableOpacity
style={styles.addView}
onPress={() => {
sqlite_wrapper
.insert({ prodName: prodName }, sqlite_wrapper.collection_product)
.then((result) => {
console.log('---result---');
console.log(result);
if (result.rowsAffected) {
fetchAllData();
}
});
function fetchAllData() {
sqlite_wrapper
.readAll(sqlite_wrapper.collection_product)
.then((resultData) => {
console.log('---resultData---');
console.log(resultData);
setData(resultData);
setProdName('');
});
}
// without sql this is how to update the state having a array
// const updatedArray = [...data];
// updatedArray.push({prodName: prodName});
// setData(updatedArray);
// setProdName('');
}}>
<Icon name="plus" size={16} style={styles.add} color="white" />
</TouchableOpacity>
</Animatable.View>
<Animatable.View
animation="bounceInLeft"
duration={1500}
style={{ flex: 1 }}>
<FlatList
data={data}
keyExtractor={(item) => item.id}
renderItem={renderItem}
/>
</Animatable.View>
</View>
);
};
var styles = StyleSheet.create({
container: {
flex: 1,
},
inputFieldView: {
flexDirection: 'row',
alignItems: 'center',
alignSelf: 'stretch',
margin: 10,
},
textInput: {
flex: 1,
backgroundColor: '#b2ebf2',
borderTopLeftRadius: 7,
borderBottomLeftRadius: 7,
fontSize: 16,
},
addView: {
backgroundColor: '#0f4c75',
alignSelf: 'stretch',
alignItems: 'center',
justifyContent: 'center',
borderTopEndRadius: 7,
borderBottomEndRadius: 7,
padding: 9,
},
add: {
padding: 7,
},
listView: {
padding: 20,
backgroundColor: 'green',
margin: 0,
borderRadius: 0,
},
listViewText: {
color: 'white',
},
});
export default AddProductList;

Unable to resolve "constants/categories.json" from "screens\GridFilter\GridFilter.js"

I'm new at react-native and trying to build an app. When I try to run my code I'm getting this error................................................................
Failed building JavaScript bundle. Unable to resolve
"constants/categories.json" from "screens\GridFilter\GridFilter.js"
GridFilter.js:
import React from 'react';
import { StyleSheet, Text, View, FlatList, Dimensions, TouchableOpacity } from 'react-native';
import categories from 'constants/categories.json';
import filterIcons from 'components/Icons/filterIcons';
import { isIphoneX } from 'utils';
import fonts from 'theme/fonts';
const formatData = (data, numColumns) => {
const numberOfFullRows = Math.floor(data.length / numColumns);
let numberOfElementsLastRow = data.length - numberOfFullRows * numColumns;
while (numberOfElementsLastRow !== numColumns && numberOfElementsLastRow !== 0) {
data.push({ key: `blank-${numberOfElementsLastRow}`, empty: true });
numberOfElementsLastRow++;
}
return data;
};
const numColumns = 3;
const WIDTH = Dimensions.get('window').width;
function GridFilter({ navigation: { navigate } }) {
const renderItem = ({ item }) => {
if (item.empty === true) {
return <View style={[styles.item, styles.itemInvisible]} />;
}
const Icon = filterIcons[item.icon];
return (
<TouchableOpacity style={styles.item} onPress={() => navigate('SearchTopBarStack')}>
<View style={styles.iconWrapper}>
<Icon width={50} height={50} color="#9f9f9f" />
</View>
<Text style={styles.itemText}>{item.name}</Text>
</TouchableOpacity>
);
};
return (
<View style={styles.container}>
<FlatList
data={formatData(categories, numColumns)}
style={styles.wrapper}
renderItem={renderItem}
numColumns={numColumns}
contentContainerStyle={{ paddingBottom: 150 }}
/>
</View>
);
}
export default GridFilter;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
paddingTop: isIphoneX ? 40 : 20,
},
wrapper: {
flex: 1,
},
iconWrapper: {
margin: 10,
},
item: {
alignItems: 'center',
justifyContent: 'center',
flex: 1,
height: WIDTH / numColumns, // approximate a square
padding: 20,
borderColor: 'gray',
borderWidth: 1,
borderRadius: 5,
backgroundColor: '#f3f3f3',
margin: 5,
},
itemInvisible: {
backgroundColor: 'transparent',
},
itemText: {
color: 'black',
textAlign: 'center',
fontFamily: fonts.REGULAR,
},
});
I tried to delete node modules and rebuild. What should I do?
You should refer to your current directory or file in your import. Try to use './' or '../' when you import path. If you use vscode it will give you auto completions.
"../../" is worked for me.