i'm working on my first react native app that uses the Navigator and i have encountered an issue. Anytime i press on the <TouchableOpacity /> to make the push to the navigator, the app freezes and can't be press again.
here's my code
```
import React, { Component } from 'react';
import {AppRegistry, Navigator, Text, TouchableOpacity} from 'react-native';
import App from './src/App';
import SinglePost from './src/components/SinglePost';
class AppNavigator extends Component{
renderScene(route, navigator){
var navProps = {navigator};
switch (route.id) {
case "postsList":
console.log(route)
return (
<TouchableOpacity onPress={() => navigator.push({id:'yes'})}>
<Text>Hey</Text>
</TouchableOpacity>
)
case "singlePost":
return <SinglePost title="Post"/>
case "yes":
console.log("yes route ",route)
return <Text>Yes</Text>
default:
return <Text>Yes</Text>
}
}
render(){
return (
<Navigator
initialRoute={{id: "postsList"}}
renderScene={this.renderScene}
/>
)
}
}
AppRegistry.registerComponent('SocialMe', () => AppNavigator);
```
When I click the yes, it just freezes, any explanation for this and how can I resolve this? Thanks
Found the problem. I noticed that this only happens when I'm debugging Js remotely. If I disable it, then all works fine
Related
I'm using react native navigation bottom tabs, and I want to create a custom "bottom sheet" popup component, but I want that component to come over the bottom tabs. Does anybody know how to position elements on top of the bottom tabs?
Yes! You have to use react-native-portalize. Just wrap the elements you want to be rendered on top in a <Portal></Portal>. This will place it above a Bottom Tab navigator.
import { Portal } from 'react-native-portalize';
const FooterButton = () => {
return(
<Portal>
<View>
<Text>I appear above the Tab Navigator!</Text>
</View>
</Portal>
);
export default FooterButton;
Don't forget to wrap the whole app in the the Host:
//In app.js
import { Host } from 'react-native-portalize';
const App = () => {
return (
<Host>
<NavigationContainer>
<AppNavigator />
</NavigationContainer>
</Host>
)
}
export default App;
NOTE: The elements inside the Portal, do not clear when the navigator navigates to another screen. So to get around this, you have to only display the Portal, when the screen is active. Thankfully React Navigation 5+ provides a useIsFocused hook that accomplishes this perfectly.
import { Portal } from 'react-native-portalize';
import { useIsFocused } from '#react-navigation/native';
const FooterButton = () => {
const isFocused = useIsFocused();
// Only display the button when screen is focused. Otherwise, it doesn't go away when you switch screens
return isFocused ? (
<Portal>
<View style={styles.buttonContainer}>
<View style={styles.footer}>{props.children}</View>
</View>
</Portal>
) : null;
};
export default FooterButton;
If you want a modal-style popup, you can wrap react-native-modalize and wrap it with react-native-modalize
Thanks to livin52 on Reddit for the solution
The only other similar question I could find here involved redux which I'm not familiar with. I don't have a lot of code, I'd like a simple Filter to pop up with a list of stores represented by checkboxes. It seems to work when I console.log to see my object state, except that the checkboxes don't visibly show a change until I close and then reopen the modal. Perhaps I'm misunderstanding how modals or state works. Example: I check box 1 and console log shows the state changed but the box still looks unchecked. I close the modal and reopen, box 1 is now checked.
import React, { useState } from "react";
import {
Button,
FlatList,
Modal,
StyleSheet,
TouchableOpacity,
View,
} from "react-native";
import AppText from "./AppText";
import { MaterialCommunityIcons } from "#expo/vector-icons";
import colors from "../config/colors";
import { CheckBox } from 'react-native-elements';
function FilterPicker({
filterStores,
setFilterStores,
}) {
const [modalVisible, setModalVisible] = useState(false);
function onCheckChanged(id) {
const index = filterStores.findIndex(x => x.id === id);
filterStores[index].checked = !filterStores[index].checked;
setFilterStores(filterStores);
console.log(JSON.stringify(filterStores));
}
return (
<>
<TouchableOpacity onPress={() => setModalVisible(true)}>
<View style={styles.Filter}>
<MaterialCommunityIcons
name="tune"
color={colors.black}
size={30}
style={styles.Icon}
/>
</View>
</TouchableOpacity>
<Modal visible={modalVisible} onRequestClose={()=> setModalVisible(false)} animationType="slide">
<View>
{
filterStores.map((item,key) => <CheckBox title={item.key} key={key} checked={item.checked} onPress={()=>onCheckChanged(item.id)}/>)
}
</View>
</Modal>
</>
);
}
export default FilterPicker;
try after modifying your onCheckChanged function like following.
you are mutating filterStores
function onCheckChanged(id) {
const index = filterStores.findIndex(x => x.id === id);
const newFilterStores = [...filterStores];
newFilterStores[index] = {...newFilterStores[index],checked:!newFilterStores[index].checked};
setFilterStores(newFilterStores);
console.log(JSON.stringify(newFilterStores));
}
In my opinion, because the state doesn't change so it doesn't re-render
When I use props.navigation.navigate("example"), it works normally. But if I import the component on another page it doesn't work anymore, props returns an empty object.
Works Fine:
const Menu = props =>{
console.log(props)
return(
<View style={styles.menuStyle}>
<TouchableOpacity style={styles.topicDiv} onPress={() =>props.navigation.navigate("Ads")}>
<View>
<Image style={styles.topicStyle} source={require ("../assets/security-camera.png")}/>
<Text style={styles.textStyle}>Câmeras</Text>
<Text style={styles.subTextStyle}>Veja como está a praia ao vivo 📷</Text>
If i try import Menu, navigation does not work:
import React from "react";
import { View } from "react-native";
import Menu from "./menu";
const Supermenu = () =>{
return(
<View>
<Menu></Menu>
</View>
)
}
export default Supermenu
If you use <Menu> inside of another component like <Supermenu>, React Navigation has no way to pass its navigation property in there. It only happens automatically if a component is a direct child of a screen (or its component property).
To have navigation available in Menu regardless of its position in the hierarchy, as long as it's a child of <NavigationContainer>, the best way is to make use of the useNavigation hook:
import { useNavigation } from '#react-navigation/core';
const Menu = props =>{
const navigation = useNavigation();
return (
<View style={styles.menuStyle}>
<TouchableOpacity style={styles.topicDiv} onPress={() => navigation.navigate("Ads")}>
...
See documentation for more detail.
If you are on an older version, there was also a HOC withNavigation that you could use.
You could also do the same in Supermenu and then pass navigation down manually.
use import {userNavigation} from '#react-navigation/core' instead of props navigate or you can add navigation props to the Menu component.
I was using react-native-barcode-scanner-google but its not working now.i have two screen on my home page one of them is barcode scanner screen.when i click on barcode screen i got message "unfortunatly the app has stoped".I also try other barcode scanner libraries but not working.Im new to react native,So any help would be highly appreciated.
Sample code
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View, Alert } from 'react-native';
import BarcodeScanner from 'react-native-barcode-scanner-google';
export default class BarcodeApp extends Component {
render() {
return (
<View style={{flex: 1}}>
<BarcodeScanner
style={{flex: 1}}
onBarcodeRead={({data, type}) => {
// handle your scanned barcodes here!
// as an example, we show an alert:
Alert.alert(`Barcode '${data}' of type '${type}' was scanned.`);
}}
/>
</View>
);
}
}
AppRegistry.registerComponent('BarcodeApp', () => BarcodeApp);
I am using react native to build project and I am facing a problem with long launch time, I try to follow https://reactnative.dev/docs/ram-bundles-inline-requires, however it is not so clear about Investigating the Loaded Modules, and how to put only the necessary modules for first screen.
I am not also able to find index.(ios|android).js file (is it index.android.bundle).
If you can tell me how to extract only necessary modules and recommend docs or examples about implementing that?
With considering the official documents, pay attention to this example:
You have a Main screen (view) in your app like HomeScreen
In your HomeScreen, there are more and more components and logic in this page but assume we have a SettingsModal.
usually, modals will open when you touch a button.
Without inline require
you have to import your modal component to your HomeScreen at the top level of your module
with inline require
you will import your modal component to your HomeScreen when it needs to show!
Let's do this with code:
HomeScreen without inline require
import React, {useState} from 'react'
import {View, Text, Pressable} from 'react-native'
import SettingsModal from 'components/modal'
function HomeScreen() {
const [showModal, setShowModal] = useState(false)
const handleShowModal = () => setShowModal(prevState => !prevState)
return (
<View>
<Text> Home Screen </Text>
<Pressable onPress={handleShowModal}>
<Text> show settings </Text>
</Pressable >
{
showModal
? <SettingsModal />
: null
}
</View>
)
}
In the above example, we import SettingsModal in our HomeScreen top level with React and View and Text...
HomeScreen with inline require
import React, {useState} from 'react'
import {View, Text, Pressable} from 'react-native'
let SettingsModal = null;
function HomeScreen() {
const [showModal, setShowModal] = useState(false)
const handleShowModal = prevState => {
if (SettingsModal == null) {
SettingsModal = require('components/modal').SettingsModal
}
setShowModal(prevState => !prevState)
}
return (
<View>
<Text> Home Screen </Text>
<Pressable onPress={handleShowModal}>
<Text> show settings </Text>
</Pressable >
{
showModal
? <SettingsModal />
: null
}
</View>
)
}
In the above example, we check if SettingsModal has not been imported yet, then we will import this component to our HomeScreen file (after user touch the show settings button)