Getting undefined device.map error while displaying table react-native-table-component - react-native

I am a developing a React Native app.My requirement is to display data from API in the table format.I am using react-native-table-component.I am not able to traverse through an array to display data in the table.Below is my code:
TargetSetUpPage.js:
import React, { useEffect } from "react";
import { StyleSheet, Text, Button, TextInput, ScrollView ,View}
from "react-native";
import { useDispatch,useSelector } from "react-redux";
import * as authActions from "../../store/actions/auth";
import AsyncStorage from '#react-native-
community/asyncstorage';
import { Table, Row, Rows } from 'react-native-table-
component';
const TargetSetUpPage = (props) => {
const [targetid, setTargetId] = React.useState("");
const dispatch = useDispatch();
const devices = [useSelector(state =>
state.auth.availableDevice)];
//console.log('The devices are: '+JSON.stringify(devices));
if (typeof(devices) !== 'undefined' && devices != null) {
console.log('Not Undefined and Not Null')
} else {
console.log('Undefined or Null')
const devices = [useSelector(state =>
state.auth.availableDevice)];
}
const tableHead = ['Target Id','Target Name']
const tableRow = devices;
console.log(devices);
const tableRows = (devices || []).map(item => ({ name:
item.name
}));
useEffect(() => {
const onScreenLoad = async() => {
const useridfordevices = await
AsyncStorage.getItem("userDatauserid");
const obj = JSON.parse(useridfordevices);
const { userid } = obj;
var userid1 = userid[0];
await dispatch(authActions.getDeviceInfo(userid1))
};
onScreenLoad();
},[dispatch]);
return (
<ScrollView showsVerticalScrollIndicator={true}>
<View>
{/* <Table borderStyle={{borderWidth: 2, borderColor:
'#c8e1ff'}}>
<Row data={tableHead} style={styles.head} textStyle=
{styles.text}/>
<Rows data={tableRows} textStyle={styles.text}/>
</Table> */}
<FlatList
data={devices}
keyExtractor={item => item.TargetId}
renderItem={itemData => (
<View style={styles.card}>
{/* <Text style={styles.text}>{itemData.item.TargetName}
</Text> */}
<Button title={itemData.item.TargetName} onPress={()=>{}}/>
</View>
)}
numColumns={2}
/>
<Text style={styles.headingTitle}>
Set your target and start running:
</Text>
<Text style={styles.textstyle}>Target ID</Text>
<TextInput
style={styles.input}
value={targetid}
onChangeText={(targetid) => setTargetId(targetid)}
></TextInput>
<Button
title="Add"
// onPress = {() => }
/>
</View>
</ScrollView>
);
};
const styles = StyleSheet.create({
input: {
height: 40,
width: "80%",
margin: 12,
borderWidth: 1,
padding: 10,
},
headingTitle: {
fontSize: 30,
},
textstyle: {
paddingTop: 10,
fontSize: 20,
},
compact: {
flexDirection: "row",
},});
export default TargetSetUpPage;
After executing it is showing the below tableRow array in console:
Not Undefined and Not Null
Array [
undefined,
]
TypeError: undefined is not an object (evaluating 'item.name')
But If I remove Table and display FlatList,I am able to display the list without any problem .I dont know what mistake I am doing in displaying the Table.Thanks in Advance.

// devices will be the same as auth.availableDevice in your redux
// If auth.availableDevice is undefined at any point, like during boot
// then devices will be undefined too
const devices = useSelector(state => state.auth.availableDevice);
// Let's write our map code so that it handles the case where devices is undefined
const tableRows = (devices || []).map(item => ({ name: item.name }));

I used DataTable from react-native-paper to get the table.Below is the code that renders data from API.
TargetSetUpPage.js:
import React, {useEffect} from "react";
import {StyleSheet, Text, Button, TextInput, ScrollView, View, FlatList}
from "react-native";
import {useDispatch, useSelector} from "react-redux";
import * as authActions from "../../store/actions/auth";
import AsyncStorage from '#react-native-community/async-storage';
import {DataTable} from 'react-native-paper';
const TargetSetUpPage = (props) => {
const [targetid, setTargetId] = React.useState("");
const dispatch = useDispatch();
const devices = useSelector(state => state.auth.availableDevice);
useEffect(() => {
const onScreenLoad = async () => {
const useridfordevices = await
AsyncStorage.getItem("userDatauserid");
const obj = JSON.parse(useridfordevices);
const {userid} = obj;
var userid1 = userid[0];
await dispatch(authActions.getDeviceInfo(userid1))
};
onScreenLoad();
}, [dispatch]);
return (
<ScrollView showsVerticalScrollIndicator={true}>
<View>
<DataTable>
<DataTable.Header>
<DataTable.Title>
<Text>Target Id</Text>
</DataTable.Title>
<DataTable.Title>
<Text>Target Name</Text>
</DataTable.Title>
</DataTable.Header>
{devices.map((item, key) => (
<DataTable.Row>
<DataTable.Cell>{item.TargetId}</DataTable.Cell>
<DataTable.Cell>{item.TargetName}</DataTable.Cell>
</DataTable.Row>
)
)}
</DataTable>
<Text style={styles.headingTitle}>
Set your target and start running:
</Text>
<Text style={styles.textstyle}>Target ID</Text>
<TextInput
style={styles.input}
value={targetid}
onChangeText={(targetid) => setTargetId(targetid)}
></TextInput>
<Button title="Add"
// onPress = {() => }
/>
</View>
</ScrollView>
);
};
const styles = StyleSheet.create({
input: {
height: 40,
width: "80%",
margin: 12,
borderWidth: 1,
padding: 10,
},
headingTitle: {
fontSize: 30,
},
textstyle: {
paddingTop: 10,
fontSize: 20,
},
compact: {
flexDirection: "row",
},
});
export default TargetSetUpPage;
which displays the table on the screen as shown below.

Related

Nested lists - How to modify (delete, add, update) items from a nested list using item's buttons and useState?

My first idea was to try to delete items from a nested list. I've started using SectionList and a component that has an useState that manages the data changes of the SectionList. I'm trying to solve it using SectionList but it'd be great to display all possible alternatives (FlatList, ViewList, etc).
I figured out how to delete a whole section list (and his items) but not one item by one. I've read plenty of posts, but I did find nothing related to managing SectionList items. Maybe there's an answer out there for FlatList nested items.
Here I left an example code ready to use (without styles) based on React Native official docs:
import React, { useEffect } from "react";
import { StyleSheet, Text, View, SafeAreaView, SectionList, StatusBar, Button } from "react-native";
import { useState } from "react";
const dataResource = [
{
title: "Main dishes",
data: ["Pizza", "Burger", "Risotto"],
n: "delete",
k: 1
},
{
title: "Sides",
data: ["French Fries", "Onion Rings", "Fried Shrimps"],
n: "delete",
k: 2
},
];
function App() {
const [state, setState] = useState(dataResource)
const Item = ({ dish, obj, i}) => (
<View >
<Text >{dish} </Text>
<Button title={obj.n} onPress={() => {}} /> // add the handler
</View>
);
const SectionComponent = ({ t, k }) => (
<View>
<Text >{t} </Text>
<Button title={'section'} onPress={() => { setState(state.filter(e => e.k != k)) }} />
</View>
);
return (
<SafeAreaView >
<SectionList
sections={state}
keyExtractor={(item, index) => item + index}
renderItem={({ item, section, index}) => <Item dish={item} obj={section} i={index}/>}
renderSectionHeader={({ section: { title, k } }) => <SectionComponent k={k} t={title} />}
/>
</SafeAreaView>
);
}
export default App;
I think how you display the data is trivial. The component you use will just change how you access the data, not how you update it. What you need is helper functions for editing the data. With those in place you can do things like add/remove section items, and editing section items themselves:
import React, { useState } from 'react';
import {
Text,
View,
StyleSheet,
SafeAreaView,
SectionList,
Button,
TextInput,
} from 'react-native';
const dataResource = [
{
title: 'Main dishes',
data: ['Pizza', 'Burger', 'Risotto'],
id: 1,
},
{
title: 'Sides',
data: ['French Fries', 'Onion Rings', 'Fried Shrimps'],
id: 2,
},
];
export default function App() {
const [state, setState] = useState(dataResource);
const [sectionTitle,setSectionTitle] = useState('Drinks')
const editItem = (itemId, newValue) => {
let newState = [...state];
let itemIndex = newState.findIndex((item) => item.id == itemId);
if (itemIndex < 0) return;
newState[itemIndex] = {
...newState[itemIndex],
...newValue,
};
setState(newState);
};
const addSectionItem = (title)=>{
let newState = [...state]
newState.push({
title,
data:[],
id:newState.length+1
})
setState(newState)
}
const removeFood = (itemId, food) => {
let currentItem = state.find((item) => item.id == itemId);
console.log(currentItem);
currentItem.data = currentItem.data.filter((item) => item != food);
console.log(currentItem.data);
editItem(itemId, currentItem);
};
const addFood = (itemId, food) => {
let currentItem = state.find((item) => item.id == itemId);
console.log(currentItem.data);
currentItem.data.push(food);
console.log(currentItem.data);
editItem(itemId, currentItem);
};
const Item = ({ item, section, index }) => {
return (
<View style={styles.row}>
<Text>{item} </Text>
<Button
title={'Delete'}
onPress={() => {
removeFood(section.id, item);
}}
/>
</View>
);
};
const SectionHeader = ({ title, id }) => {
return (
<View style={styles.header}>
<Text style={{ fontSize: 18 }}>{title} </Text>
<Button
title={'X'}
onPress={() => {
setState(state.filter((e) => e.id != id));
}}
/>
</View>
);
};
const SectionFooter = ({ id }) => {
const [text, setText] = useState('');
return (
<View style={[styles.row, styles.inputWrapper]}>
<Text>Add Entry</Text>
<TextInput
value={text}
onChangeText={setText}
style={{ borderBottomWidth: 1 }}
/>
<Button title="Add" onPress={() => addFood(id, text)} />
</View>
);
};
return (
<SafeAreaView>
<Button title="Reset list" onPress={() => setState(dataResource)} />
<View style={[styles.row, styles.inputWrapper]}>
<Text>Add New Section</Text>
<TextInput
value={sectionTitle}
onChangeText={setSectionTitle}
style={{ borderBottomWidth: 1 }}
/>
<Button title="Add" onPress={() => addSectionItem(sectionTitle)} />
</View>
<View style={styles.sectionListWrapper}>
<SectionList
sections={state}
keyExtractor={(item, index) => item + index}
renderItem={Item}
renderSectionHeader={({ section }) => <SectionHeader {...section} />}
renderSectionFooter={({ section }) => <SectionFooter {...section} />}
/>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
row: {
flexDirection: 'row',
width: '100%',
justifyContent: 'space-between',
padding: 5,
alignItems: 'center',
},
header: {
flexDirection: 'row',
paddingVertical: 5,
width: '100%',
borderBottomWidth: 1,
},
inputWrapper: {
paddingVertical: 15,
marginBottom: 10,
},
sectionListWrapper: {
padding: 5,
},
});
Here's a demo
I've improved my answer to give a clearer example of how to manipulate SectionList. An example of how to add/delete/modify sections and its data is provided.
import React from 'react';
export default function useStateHelpers(state, setState) {
const editSection = (sectionId, newValue) => {
// parse and stringify is used to clone properly
let newState = JSON.parse(JSON.stringify(state));
let itemIndex = newState.findIndex((item) => item.id == sectionId);
if (itemIndex < 0) return;
const section = {
...newState[itemIndex],
...newValue,
};
newState[itemIndex] = section;
setState(newState);
};
const editSectionDataItem = (sectionId, itemId, newValue) => {
const newState = JSON.parse(JSON.stringify(state));
const sectionIndex = newState.findIndex(
(section) => section.id == sectionId
);
const section = newState[sectionIndex];
const itemIndex = section.data.findIndex((item) => item.id == itemId);
let item = section.data[itemIndex];
section.data[itemIndex] = {
...item,
...newValue,
};
editSection(sectionId, section);
};
const editSectionTitle = (sectionId, title) =>
editSection(sectionId, { title });
const setSelectSectionItem = (sectionId, itemId, isSelected) => {
editSectionDataItem(sectionId, itemId, { isSelected });
};
const removeSectionDataItem = (sectionId, food) => {
let newState = JSON.parse(JSON.stringify(state));
let sectionIndex = newState.findIndex((section) => section.id == sectionId);
let section = newState[sectionIndex];
section.data = section.data.filter((item) => item.title != food);
editSection(sectionId, section);
};
const addSectionDataItem = (sectionId, title, price) => {
let newState = JSON.parse(JSON.stringify(state));
let sectionIndex = newState.findIndex((section) => section.id == sectionId);
let section = newState[sectionIndex];
section.data.push({
title,
price,
id: `section-${sectionId}-${section.data.length + 1}`,
});
editSection(sectionId, section);
};
const addSection = (title, data = [], id) => {
let newState = JSON.parse(JSON.stringify(state));
newState.push({
title,
data,
id: newState.length + 1,
});
setState(newState);
};
const helpers = {
editSection,
editSectionTitle,
removeSectionDataItem,
addSectionDataItem,
addSection,
setSelectSectionItem,
editSectionDataItem,
};
return helpers;
}
import React, { useState } from 'react';
import {
StyleSheet,
SafeAreaView,
View,
Button,
SectionList,
} from 'react-native';
import data from './data';
import StateContext from './StateContext';
import useStateHelpers from './hooks/useStateHelpers';
import Header from './components/SectionHeader';
import Footer from './components/SectionFooter';
import Item from './components/SectionItem';
import TextInput from './components/Input';
export default function App() {
const [state, setState] = useState(data);
const [sectionTitle, setSectionTitle] = useState('');
const helpers = useStateHelpers(state, setState);
return (
<SafeAreaView style={{ flex: 1 }}>
<StateContext.Provider value={{ state, setState, ...helpers }}>
<View style={styles.container}>
<Button title="Reset list" onPress={()=>setState(data)} />
<TextInput
label={'Add New Section'}
value={sectionTitle}
onChangeText={setSectionTitle}
onRightIconPress={() => {
helpers.addSection(sectionTitle);
setSectionTitle('');
}}
/>
<View style={styles.sectionListWrapper}>
<SectionList
style={{ flex: 1 }}
sections={state}
renderItem={(props) => <Item {...props} />}
renderSectionHeader={(props) => <Header {...props} />}
renderSectionFooter={(props) => <Footer {...props} />}
/>
</View>
</View>
</StateContext.Provider>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 8,
},
sectionListWrapper: {
padding: 5,
flex: 1,
},
});
import React, { useContext } from 'react';
import { View, TouchableOpacity, StyleSheet, Text, Button } from 'react-native';
import StateContext from '../StateContext';
export default function Item({ item, section, index }) {
const {
removeSectionDataItem,
setSelectSectionItem
} = useContext(StateContext);
const hasPrice = item.price.toString().trim().length > 0;
return (
<TouchableOpacity
style={[styles.container, item.isSelected && styles.selectedContainer]}
onPress={() =>
setSelectSectionItem(section.id, item.id, !item.isSelected)
}
>
<View style={styles.row}>
<Text>
{item.title + (hasPrice ? ' | ' : '')}
{hasPrice && <Text style={{ fontWeight: '300' }}>{item.price}</Text>}
</Text>
<Button
title={'Delete'}
onPress={() => {
removeSectionDataItem(section.id, item.title);
}}
/>
</View>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
container: {
marginVertical: 2,
},
selectedContainer: {
backgroundColor: 'rgba(0,0,0,0.2)',
},
row: {
flexDirection: 'row',
width: '100%',
justifyContent: 'space-between',
padding: 5,
alignItems: 'center',
},
});
/*SectionFooter.js*/
import React, { useState, useContext, useEffect } from 'react';
import { View, StyleSheet, Text } from 'react-native';
import TextInput from './Input';
import StateContext from '../StateContext';
export default function SectionFooter({ section }) {
const [title, setTitle] = useState('');
const [price, setPrice] = useState('');
const [titleWasEdited, setTitleWasEdited] = useState(false);
const { addSectionDataItem, editSectionDataItem } = useContext(StateContext);
const selectedItem = section.data.find((item) => item.isSelected);
// listen for item selection
useEffect(() => {
// pass item values to text input
setTitle(selectedItem?.title || '');
setPrice(selectedItem?.price || '');
// reset title/price input
setTitleWasEdited(false);
}, [selectedItem]);
return (
<View style={styles.container}>
<Text>
{selectedItem
? 'Editing ' + selectedItem.title
: 'Add New Entry'
}
</Text>
{/*one input handles both title and price*/}
<TextInput
label={titleWasEdited ? 'Price' : 'Title'}
value={titleWasEdited ? price : title}
onChangeText={titleWasEdited ? setPrice : setTitle}
rightIconName={titleWasEdited ? 'plus' : 'arrow-right'}
// rightIcon is disabled when theres no text
// but price is allowed to be empty
allowEmptySubmissions={titleWasEdited}
style={{ width: '80%' }}
onRightIconPress={() => {
// after title is edited allow submission
if (titleWasEdited) {
// if item was edited update it
if (selectedItem) {
editSectionDataItem(section.id, selectedItem.id, {
title,
price,
isSelected: false,
});
}
// or add new item
else {
addSectionDataItem(section.id, title, price);
}
setTitle('');
setPrice('');
}
// toggle between title & price
setTitleWasEdited((prev) => !prev);
}}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
marginVertical: 20,
alignItems: 'center',
},
});
import React, { useContext } from 'react';
import { View, StyleSheet } from 'react-native';
import { TextInput } from 'react-native-paper';
import StateContext from '../StateContext';
export default function SectionHeader({ section: { id, title } }) {
const { editTitle, setState, state } = useContext(StateContext);
return (
<View style={{ borderBottomWidth: 1 }}>
<View style={styles.header}>
<TextInput
style={styles.titleInput}
value={title}
onChangeText={(text) => {
editTitle(id, text);
}}
right={
<TextInput.Icon
name="close"
onPress={() => {
setState(state.filter((sec) => sec.id != id));
}}
/>
}
underlineColor="transparent"
activeUnderlineColor="transparent"
outlineColor="transparent"
activeOutlineColor="transparent"
selectionColor="transparent"
dense
/>
</View>
</View>
);
}
const styles = StyleSheet.create({
header: {
flexDirection: 'row',
width: '100%',
justifyContent: 'space-around',
alignItems: 'center',
},
titleInput: {
fontSize: 18,
backgroundColor: 'transparent',
borderWidth: 0,
borderColor: 'transparent',
height: 36,
},
});

React native flatlist inverted onscrollbegin runs every time I scrol

I want to use onScrollBegin on my flatlist. But everytime I make scroll the function runs. I only want to run this function when I am at the top, not everytime I scroll.
import * as React from 'react';
import { StyleSheet, Text, View, Pressable, Image, Dimensions, Platform, FlatList, TextInput } from 'react-native';
import { messages } from '../utils/mockChat';
import { useDispatch, useSelector } from 'react-redux';
import moment from 'moment';
import Modal from 'react-native-modalbox';
import { openModalImage } from '../redux/slice/chat/chatSlice';
const { width, height } = Dimensions.get('screen');
function propsEqual(prevProp, nextProp) {
if(prevProp.id === nextProp.id) {
return true;
}
}
const Item = React.memo(({ global_user_id, id, type, render, allDates, name, user_id, reciever, text, images, video, sending, pending, read, date }) => {
const dateNum = moment(date).format('DD-MM-YYYY');
return (
<View style={s.item}>
<View style={s.itemContainer}>
<View style={global_user_id === user_id ? s.ownerText : s.reciever_text}>
<Text style={s.text}>{ text }</Text>
</View>
</View>
</View>
)
}, propsEqual);
const userState = state => state.user.userID;
const modalState = state => state.chatSlice.modalImage;
const Chat = ({ route, navigation }) => {
const { image } = route.params;
const dispatch = useDispatch();
const modalSec = useSelector(modalState);
const userID = useSelector(userState);
const [message, setMessage] = React.useState(generateItems(messages));
const modalR = React.useRef(null);
const timerCloseModal = React.useRef(null);
React.useEffect(() => {
modalSec && modalR.current.open();
}, [modalSec]);
const dates = new Set();
function renderDate(date) {
dates.add(moment(date).format('DD-MM-YYYY'));
return (
<Text style={{color: '#333', fontSize: 12}}>{moment(date).format('DD-MM-YYYY')}</Text>
)
}
const showFooter = () => {
return (
<View style={s.footerContainer}>
<TextInput style={{height: 50, width: '100%', padding: 20}} />
</View>
)
};
const rowRenderer = ({ item }) => {
return (
<Item
item={item}
id={item.id}
allDates={dates}
render={(date) => renderDate(date)}
global_user_id={userID}
name={item.name}
user_id={item.user_id}
reciever={item.reciever}
text={item.text}
images={item.images}
video={item.video}
sending={item.sending}
pending={item.pending}
read={item.read}
type={item.type}
date={item.date} />
)
};
const closeModalImage = React.useCallback(() => {
dispatch(openModalImage());
}, [dispatch, modalR]);
return (
<View style={s.container}>
<FlatList
data={message}
keyExtractor={i => i.id.toString()}
renderItem={rowRenderer}
initialNumToRender={10}
onScrollBeginDrag={() => {
console.log('s');
// setMessage(items);
}}
extraData={message}
ListHeaderComponent={showFooter}
inverted
/>
</View>
)
};
const s = StyleSheet.create({
container: {
flex: 1
},
modal: {
justifyContent: 'center',
alignItems: 'center',
width: 300,
height: 300,
borderRadius: 200,
backgroundColor: 'transparent',
maxHeight: 500,
},
item: {
backgroundColor: 'red',
height: 250,
width: width * 0.8,
marginVertical: 12
},
ownerText: {
alignSelf: 'flex-end',
backgroundColor: 'blue'
},
reciever_text: {
alignSelf: 'flex-start'
}
});
export default Chat;
How can I fix it, that I can only scroll if I am on the top? I use inverted so its hard for me, to know where is the top position. I am very thankful for your help
Make use of the onEndReached prop.
The onEndReached function calls every time you reach the end of a list.
official doc

React Native: navigation

I'm new to react native, this is an application that scans Qr codes I want to have two buttons one that scans again and one that redirects to a new screen called 'List' with the QR code data. However after scanning the QR code and every time i press the scan again or result button the expo application crashes this is my code:
import React, { useState, useEffect } from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { BarCodeScanner } from 'expo-barcode-scanner';
import { Link } from "react-router-dom"
import CryptoJS from 'crypto-js';
import { decode } from 'base-64';
import { useNavigation } from '#react-navigation/native';
export default function Scan({ navigation }) {
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(false);
const [text, setText] = useState('Not yet scanned')
const askForCameraPermission = () => {
(async () => {
const { status } = await BarCodeScanner.requestPermissionsAsync();
setHasPermission(status === 'granted');
})()
}
// Request Camera Permission
useEffect(() => {
askForCameraPermission();
}, []);
// What happens when we scan the bar code
const handleBarCodeScanned = ({ type, data }) => {
setScanned(true);
var master_key = '5486231058798416'
// Decode the base64 data so we can separate iv and crypt text.
var rawData = decode(data);
// Split by 16 because my IV size
var iv = rawData.substring(0, 16);
var crypttext = rawData.substring(16);
//Parsers"
crypttext = CryptoJS.enc.Latin1.parse(crypttext);
iv = CryptoJS.enc.Latin1.parse(iv);
var key = CryptoJS.enc.Utf8.parse(master_key);
// Decrypt
var plaintextArray = CryptoJS.AES.decrypt(
{ ciphertext: crypttext},
key,
{iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7}
);
// Can be Utf8 too
var output_plaintext = CryptoJS.enc.Latin1.stringify(plaintextArray).json();
console.log("plain text : " + output_plaintext);
setText(output_plaintext.json())
console.log('Type: ' + type + '\nData: ' + data)
};
// Check permissions and return the screens
if (hasPermission === null) {
return (
<View style={styles.container}>
<Text>Requesting for camera permission</Text>
</View>)
}
if (hasPermission === false) {
return (
<View style={styles.container}>
<Text style={{ margin: 10 }}>No access to camera</Text>
<Button title={'Allow Camera'} onPress={() => askForCameraPermission()} />
</View>)
}
// Navigation
function MyBackButton() {
const navigation = useNavigation();
return (
<Button
title="Result"
onPress={() => {
navigation.navigate('List');
}}
/>
);
}
// Return the View
return (
<View style={styles.container}>
<View style={styles.barcodebox}>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={{ height: 400, width: 400 }} />
</View>
{scanned && <Button title={'Result'} onPress={() => MyBackButton()} color='black' />}
{scanned && <Button title={'Scan again?'} onPress={() => setScanned(false)} color='black' />}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
maintext: {
fontSize: 16,
margin: 20,
},
barcodebox: {
alignItems: 'center',
justifyContent: 'center',
height: 300,
width: 300,
overflow: 'hidden',
borderRadius: 30,
backgroundColor: 'black'
}
});
in your code MyBackButton not just a function, it return a view -> crash.
Fix your func MyBackButton =>
// Navigation
function MyBackButton() {
const navigation = useNavigation();
navigation.navigate('List');
}
Rename your MyBackButton -> myBackAction

Searchable flat list react native

I am trying to search items in a flatlist, whenever i type in the search bar it only take one letter and closes the keyboard and the value inside the search bar disappear,
example when i type "george" it only takes the letter g and re-render a list of names containing the letter g and delete what's inside the search bar
how can i fix this ?
import React, { useState, useEffect } from 'react';
import { ScrollView } from 'react-native';
import { View, Text, FlatList, ActivityIndicator, SafeAreaView, TouchableOpacity } from 'react-native';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { Divider, SearchBar } from 'react-native-elements'
const Item = ({ name, lastName }) => (
<View>
<Text style={{ fontSize: 17, color: '#666', marginBottom: 10 }}>Full name: {name} {lastName}</Text>
</View>);
function Clients({ navigation }) {
const [isLoading, setLoading] = useState(true);
const usersApi = 'https://reqres.in/api/users'
const [users, setUsers] = useState([]);
const [search, setSearch] = useState("");
const [masterData, setMasterData] = useState("");
const fetchJson = async (userApi) => {
const response = await fetch(userApi);
return response.json()
}
useEffect(() => {
fetchJson(usersApi)
.then((users) => {
setUsers(users.data);
setMasterData(users.data);
})
.catch((error) => (alert(error)))
.finally(() => setLoading(false));
}, []);
const itemSeparator = () => {
return (
<Divider style={{ width: "105%", marginVertical: 3, alignSelf: 'center' }} />
)
}
const renderHeader = () => {
return (
<SearchBar
placeholder="Type Here..."
lightTheme
round
onChangeText={text => searchFilterFunction(text)}
autoCorrect={false}
/>
);
};
const searchFilterFunction = text => {
setSearch(text);
const newData = masterData.filter(item => {
const itemData = `${item.first_name.toUpperCase()} ${item.last_name.toUpperCase()}`;
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
setUsers(newData);
};
const renderItem = ({ item }) => (
<TouchableOpacity style={{
flex: 1,
padding: 10
}}
onPress={() => { navigation.navigate('Client', { item: item }); }}
underlayColor='#ccc'
activeOpacity={0.1} >
<Item name={item.first_name} lastName={item.last_name} />
</TouchableOpacity>
);
console.log(search)
console.log(users)
return (
<SafeAreaProvider>
<SafeAreaView>
<Text style={{ color: '#666', margin: 15, fontSize: 20 }}>Clients actuels</Text>
<View style={{
width: '96%',
backgroundColor: 'white',
borderRadius: 5,
alignSelf: 'center',
marginTop: 20,
}}>
<View style={{ margin: 15 }}>
{isLoading ? <ActivityIndicator size="large" /> :
<FlatList
data={users}
renderItem={renderItem}
ItemSeparatorComponent={itemSeparator}
ListHeaderComponent={renderHeader}
keyExtractor={item => item.id.toString()}
value={search}
/>}
</View>
</View>
</SafeAreaView>
</SafeAreaProvider>
);
}
export default Clients;

focus next input field in functional component react native

I've created a login page where it has 2 input fields (username, password). To generate those input fields i am using "Input" component from nativebase. Now i want to focus password field from username input field when user press next from keyboard. But i am having a hard time finding this solution, can anyone help me out with that? Here is my code:
//packages
import React, { createRef, useContext, useEffect, useState } from 'react';
import { Image, Keyboard, ScrollView, StyleSheet, Text, View } from 'react-native';
import { AuthContext } from './context';
// third pirty packages
import { Button, Item, Input, Root, Spinner } from 'native-base';
import FontAwesome from "react-native-vector-icons/FontAwesome";
import Feather from "react-native-vector-icons/Feather";
import {
widthPercentageToDP as wp,
heightPercentageToDP as hp,
listenOrientationChange as lor,
removeOrientationListener as rol
} from 'react-native-responsive-screen';
//assets and components
import logoImageSmall from './../android/app/src/main/res/drawable/logo_small.png';
export const LoginScreen = ({ route, navigation }) => {
const [site_url, setSiteUrl] = useState(route.params.site_url);
const [database_name, setDatabaseName] = useState(route.params.database_name);
const [institute_name, setInstituteName] = useState(route.params.institute_name);
const [logo_location, setLogoLocation] = useState(route.params.logo_location);
const [student_id, setStudentId] = useState('');
const [password, setPassword] = useState('');
const [showLogo, setShowLogo] = useState(true);
const { state, signInAction } = useContext(AuthContext);
let passwordRef = React.createRef();
useEffect(() => {
lor();
const keyboardDidShowListener = Keyboard.addListener(
'keyboardDidShow',
() => {
_keyboardDidShow();
}
);
const keyboardDidHideListener = Keyboard.addListener(
'keyboardDidHide',
() => {
_keyboardDidHide();
}
);
return () => {
rol();
keyboardDidHideListener.remove();
keyboardDidShowListener.remove();
};
}, []);
let _keyboardDidHide = () => {
setShowLogo(true);
}
let _keyboardDidShow = () => {
setShowLogo(false);
}
const styles = StyleSheet.create({
............
// my styles
............
});
return (
<Root>
<ScrollView contentContainerStyle={styles.loginForm} keyboardShouldPersistTaps="handled">
<Item rounded style={{ borderColor: "#FF3C48" }}>
<FontAwesome name='user' style={styles.iconStyle} />
<Input
style={{ marginLeft: hp("3%") }}
placeholder='Username'
onChangeText={student_id => setStudentId(student_id)}
returnKeyType={"next"}
blurOnSubmit={false}
onSubmitEditing={el => passwordRef.current = el}
onFocus={() => setShowLogo(false)} />
</Item>
<Item rounded style={{ borderColor: "#FF3C48", marginTop: hp("3%") }}>
<FontAwesome name='unlock' style={styles.iconStyle} />
<Input
ref={passwordRef}
style={{ marginLeft: hp("3%") }}
secureTextEntry={true}
placeholder='Password'
onChangeText={password => setPassword(password)}
returnKeyType={"done"}
onFocus={() => setShowLogo(false)} />
</Item>
<Button full danger
style={{ marginTop: hp("3%") }}
onPress={() => {
// check App.js for further process
signInAction({ student_id, password, site_url, database_name });
}}>
{state.sendingRequest ? (<Spinner color='white' />) : (<Text style={{ color: '#ffffff', fontWeight: 'bold', width: '100%', textAlign: 'center', fontSize: hp("2.8%") }}> LOGIN </Text>)}
</Button>
</ScrollView>
</Root>
)
}
Use this passwordRef.current.focus()