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
Related
I am newer for using react-native, and wanna try to create a camera with filter. I'm blocked in step to recognize face. Have success to draw rectangle when face detected, but the problem is once it goes out of detection. The camera stop running as it fixes on the last real-time capture
Here is my code:
import { useState, useEffect, useRef } from 'react'
import { Camera } from 'expo-camera'
import * as MediaLibrary from 'expo-media-library'
import { Text, StyleSheet, View, TouchableOpacity } from 'react-native'
import Button from './Button'
import { Ionicons } from '#expo/vector-icons'
import * as FaceDetector from 'expo-face-detector'
export default function PCamera() {
const cameraRef = useRef(undefined)
const [faceDetected, setFaceDetected] = useState([])
const [lastImage, setImage] = useState(undefined)
const [hasUsePermssion, setUsePermission] = useState(false)
const [type, switchToType] = useState(Camera.Constants.Type.front)
const takePicture = async () => {
if (cameraRef) {
try {
const options = {
quality: 1,
base64: true,
exif: false,
}
const data = await cameraRef.current.takePictureAsync(options)
setImage(data.uri)
console.log(data)
} catch (err) {
console.error(err)
}
}
}
const swithMode = () => {
switchToType(
type === Camera.Constants.Type.front
? Camera.Constants.Type.back
: Camera.Constants.Type.front
)
}
const handleFacesDetected = ({ faces }) => {
setFaceDetected(faces)
}
useEffect(() => {
;(async () => {
const { status } = await Camera.requestCameraPermissionsAsync()
if (status === 'granted') {
setUsePermission(true)
}
})()
}, [])
if (hasUsePermssion === null) {
return <View />
}
if (hasUsePermssion === false) {
return <Text>No access to camera</Text>
}
return (
<View style={styles.cameraContainer}>
<View style={styles.overlay}>
<Camera
ref={cameraRef}
style={styles.camera}
type={type}
onFacesDetected={handleFacesDetected}
faceDetectorSettings={{
mode: FaceDetector.FaceDetectorMode.fast,
detectLandmarks: FaceDetector.FaceDetectorLandmarks.all,
runClassifications:
FaceDetector.FaceDetectorClassifications.none,
minDetectionInterval: 100,
tracking: true,
}}
>
{faceDetected.length > 0 &&
faceDetected.map((face) => (
<View
key={face.faceID}
style={{
position: 'absolute',
borderWidth: 2,
borderColor: 'red',
left: face.bounds.origin.x,
top: face.bounds.origin.y,
width: face.bounds.size.width,
height: face.bounds.size.height,
}}
/>
))}
</Camera>
</View>
<View style={styles.optionsContainer}>
<View>
<TouchableOpacity onPress={swithMode}>
<Text>
<Ionicons
name="camera-reverse-outline"
size={24}
color="black"
/>
</Text>
</TouchableOpacity>
</View>
<Button
icon="camera"
title="Take Photo"
onPress={takePicture}
style={styles.button}
/>
<View>
<Text>...</Text>
</View>
</View>
</View>
)}
const styles = StyleSheet.create({
cameraContainer: {flex: 1,
},
overlay: {
flex: 6,
borderBottomStartRadius: 75,
borderBottomEndRadius: 75,
overflow: 'hidden',
},
camera: {
flex: 1,
},
optionsContainer: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
},
})
N.B: Don't take care of the Button, it's a custom component and works well
My file name is talesrunner23 and splash.png file is in ASSETS, but when you run it, it says it can't be found
<Image source={require('/talesrunner23/assets/splash.png/')}They say I'm wrong here
please help me I'm a beginner, so I have to write down all the codes
please please
I don't know at all
*import React, { useRef, useState, useCallback, useEffect } from 'react';
import {
View,
BackHandler,
Platform,
StyleSheet,
ActivityIndicator,
} from 'react-native';
import { WebView } from 'react-native-webview';
const DELAY_BEFORE_WEBVIEW = 10; // <--- seconds before webview load
export default function App() {
// ref
const webView = useRef();
// callbacks
const handleBack = useCallback(() => {
if (canGoBack && webView.current) {
webView.current.goBack();
return true;
}
return false;
`enter code here`;
}, [canGoBack]);
// effects
useEffect(() => {
BackHandler.addEventListener('hardwareBackPress', handleBack);
return () => {
BackHandler.removeEventListener('hardwareBackPress', handleBack);
};
}, [handleBack]);
useEffect(() => {
setTimeout(() => {
setIsLoading(false);
}, 30 * DELAY_BEFORE_WEBVIEW);
}, []);
// states
const [canGoBack, setCanGoBack] = useState(false);
const [isLoading, setIsLoading] = useState(true);
return (
<View style={styles.container}>
<WebView
ref={webView}
source={{ uri: 'https://www.talesrunnerbestguild.co.kr/' }}
style={styles.webView}
onLoadProgress={(event) => setCanGoBack(event.nativeEvent.canGoBack)}
/>
{isLoading && <CenterLoader />}
</View>
);
}
const CenterLoader = () => (
<View style={styles.loaderContainer}>
<Image source={require('/talesrunner23/assets/splash.png/')}
style={{height:100,width:100}}/>
</View>
);
const styles = StyleSheet.create({
container: { flex: 1 },
loaderContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
width: '100%',
height: '100%',
backgroundColor:'white' // <-- comment this to show webview while loading
},
webView:
Platform.OS === 'ios'
? { marginTop: 30, marginBottom: 40 }
: { marginTop: 30 },
});
You will not want to require but import the Image source at the top. Here is a quick example I made in a sandbox: https://codesandbox.io/s/image-example-c4irqo?file=/src/App.js
import Cat from "./cat.jpeg";
function App() {
return (
<View style={styles.app}>
<View style={styles.header}>
<Image
accessibilityLabel="Cat"
source={Cat}
resizeMode="contain"
style={styles.logo}
/>
<Text style={styles.title}>Image Example</Text>
</View>
</View>
);
}
I want to spend more time on splash images
I want to set the time of the splash image
Splash image only appears for 1 second and then white screen. I want the first loading screen to appear only as splash image
This is my app,js file. Please add the code here
*import React, { useRef, useState, useCallback, useEffect } from "react";
import { BackHandler, Platform, StyleSheet,ActivityIndicator } from "react-native";
import { WebView } from "react-native-webview";
export default function App() {
const webView = useRef();
const [canGoBack, setCanGoBack] = useState(false);
const handleBack = useCallback(() => {
if (canGoBack && webView.current) {
webView.current.goBack();
return true;
}
return false;`enter code here`
}, [canGoBack]);
useEffect(() => {
BackHandler.addEventListener("hardwareBackPress", handleBack);
return () => {
BackHandler.removeEventListener("hardwareBackPress", handleBack);
};
}, [handleBack]);
const App = () => (
<View style={[styles.container, styles.horizontal]}>
<ActivityIndicator />
<ActivityIndicator size="large" />
<ActivityIndicator size="small" color="#0000ff" />
<ActivityIndicator size="large" color="#00ff00" />
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
horizontal: {
flexDirection: 'row',
justifyContent: 'space-around',
padding: 10,
},
});
const platformStyles = StyleSheet.create({
webView: Platform.OS === 'ios'
? { marginTop: 30, marginBottom: 40 }
: { marginTop: 30 }
});
return (
<WebView
ref={webView}
source={{ uri: "https://www.talesrunnerbestguild.co.kr/" }}
style = {platformStyles.webView}
onLoadProgress={(event) => setCanGoBack(event.nativeEvent.canGoBack)}
/>
);
}*
I have fixed this code for you!
import React, { useRef, useState, useCallback, useEffect } from 'react';
import {
View,
BackHandler,
Platform,
StyleSheet,
ActivityIndicator,
} from 'react-native';
import { WebView } from 'react-native-webview';
const DELAY_BEFORE_WEBVIEW = 10; // <--- seconds before webview load
export default function App() {
// ref
const webView = useRef();
// callbacks
const handleBack = useCallback(() => {
if (canGoBack && webView.current) {
webView.current.goBack();
return true;
}
return false;
`enter code here`;
}, [canGoBack]);
// effects
useEffect(() => {
BackHandler.addEventListener('hardwareBackPress', handleBack);
return () => {
BackHandler.removeEventListener('hardwareBackPress', handleBack);
};
}, [handleBack]);
useEffect(() => {
setTimeout(() => {
setIsLoading(false);
}, 1000 * DELAY_BEFORE_WEBVIEW);
}, []);
// states
const [canGoBack, setCanGoBack] = useState(false);
const [isLoading, setIsLoading] = useState(true);
return (
<View style={styles.container}>
<WebView
ref={webView}
source={{ uri: 'https://www.talesrunnerbestguild.co.kr/' }}
style={styles.webView}
onLoadProgress={(event) => setCanGoBack(event.nativeEvent.canGoBack)}
/>
{isLoading && <CenterLoader />}
</View>
);
}
const CenterLoader = () => (
<View style={styles.loaderContainer}>
<ActivityIndicator size="large" color="#00ff00" />
</View>
);
const styles = StyleSheet.create({
container: { flex: 1 },
loaderContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
width: '100%',
height: '100%',
backgroundColor:'white' // <-- comment this to show webview while loading
},
webView:
Platform.OS === 'ios'
? { marginTop: 30, marginBottom: 40 }
: { marginTop: 30 },
});
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
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.