pass multiple methods from parent to child component in react - javascript

I have created Table component. In this component i have created two buttons. one for download and second is share. both have onPress method. I have imported this Table component in the dashboard component. but I am unable to use both methods individually in my dashboard component.please suggest any solution for this problem.
Table Component:
import React, { StrictMode, useEffect, useState } from "react";
import { Text, View, ActivityIndicator } from "react-native";
import Size from "../../constants/Sizes";
import Strings from "../../constants/Strings";
import { Table, TableWrapper, Row, Rows } from "react-native-table-component";
import Color from "../../constants/Colors";
import Icon from "../../styles/Icons";
import api from "../../services/api";
import ListModel from "../ListModal";
import { TableTwoStyle as tableStyle } from "../../styles";
import { heightToDp } from "../../constants/Utils";
const TableTwo = (props) => {
const [files, setFiles] = useState([]);
const [modalState, setModalState] = useState(false);
useEffect(() => {
const fileData = api.getFileOptions();
setFiles(fileData);
}, []);
const { data } = props;
const handleOptions = (title) => {
console.log("title", title);
props.onPress(title);
// this.closeModal();
};
const openModal = () => {
setModalState(true);
};
const closeModal = () => {
setModalState(false);
};
return (
<StrictMode>
{data !== undefined ? (
<View style={tableStyle.mainContainer}>
<View style={tableStyle.HeadingSection}>
<View style={tableStyle.LabelContainer}>
<View style={tableStyle.leftSection}>
<Text style={tableStyle.labelText}>{Strings.tableTitle}</Text>
</View>
<View style={tableStyle.rightSection}>
<Icon.MaterialIcons
name="file-download"
color={Color.gray}
style={tableStyle.exportButton}
size={heightToDp(Size.per_4_5)}
onPress={openModal}
/>
</View>
<View style={tableStyle.rightSection}>
<Icon.MaterialIcons
name="share"
color={Color.info}
style={tableStyle.exportButton}
size={heightToDp(Size.per_4)}
onPress={openModal}
/>
</View>
</View>
<View style={tableStyle.divider} />
</View>
<View style={tableStyle.TableSection}>
{data.headers && data.headers.length > 0 ? (
<Table
borderStyle={{
borderWidth: Size.px_1,
borderColor: Color.dividerColor,
}}
>
<Row
data={data.headers}
flexArr={[Size.num_1]}
style={tableStyle.head}
textStyle={tableStyle.headerText}
/>
<TableWrapper style={tableStyle.wrapper}>
<Rows
data={data.data}
flexArr={[Size.num_1]}
style={tableStyle.row}
textStyle={tableStyle.text}
/>
</TableWrapper>
</Table>
) : (
<ActivityIndicator color={Color.loaderColor} size={Strings.lg} />
)}
</View>
<ListModel
modalState={modalState}
close={closeModal}
onPress={handleOptions}
data={files}
/>
</View>
) : null}
</StrictMode>
);
};
export default TableTwo;
Dashboard Component:
import React, { StrictMode, Component } from "react";
import { View, ScrollView } from "react-native";
import { GraphCardList as GraphList } from "../components";
import { InfoCardList as InfoList } from "../components";
import { TableTwo as Table } from "../components";
import Loader from "../components/Loader";
import Store from "../database/Storage";
import OptionsCard from "../components/Option";
import { Card as CardUI } from "../components";
import { dashboardStyle as dashboardUI } from "../styles";
import Api from "../services/api";
import inputValidation from "../helper/Validation";
import TableExport from "../exports/TableExport";
import Permission from "../services/AppPermission";
export default class DashboardScreen extends Component {
constructor(props) {
super(props);
this.state = {
tableList: [],
};
this.downloadData = this.downloadData.bind(this);
}
componentDidMount() {
}
componentWillUnmount() {
}
downloadData(title) {
...
}
shareData(){
....
}
render() {
const {
loader2,
infoList,
chartList,
tableList,
userList,
loader,
pauseState,
} = this.state;
//console.log("users",infoList);
if (loader) {
return (
<View style={dashboardUI.mainContainer}>
<Loader />
</View>
);
}
return (
<StrictMode>
<CardUI style={dashboardUI.Cards}>
<Table data={tableList} onPress={this.downloadData} />
</CardUI>
)}
</StrictMode>
);
}
}

If your'e passing same prop for two different buttons that means that the two buttons will execute the same method , but if you want to pass different methods for each button just pass a different props.
For example component B:
<View>
<Button title="Download" onPress={props.download}/>
<Button title="Share" onPress={props.share}/>
</View>
Component A:
<B download={this.downloadData} share={this.shareData}/>

Please try below code:
**In Dashboard Component:**
downloadData() {
}
`return (<Table data={tableList} handleDownloadData={this.downloadData} />);`
**In Table Component:**
const download = (data) => {
props.handleDownloadData(data);
};
const share = (data) => {
props.handleDownloadData(data);
};`
`return (<div><Button onClick={download}> Download</Button><Button onClick={share}> Share</Button></div>);
`

Related

ReactNative Context returns undefined when trying to access a value

I am trying to use the values/functions from my context but every time I console.log a value that Coes from context the value is undefined.
This is my Context:
import { NativeStackNavigationProp } from '#react-navigation/native-stack';
import React, {createContext, FC, useEffect } from 'react';
import { useState } from 'react';
import {fbInit, setNewUserFireStore, subscribeUserFS } from '../services/FirebaseServices';
const initialState = {
signedIn: false,
}
export const FirebaseContext = createContext();
export const FirebaseContextProvider = ({children}) => {
const [isUserSignedIn, setIsUserSignedIn] = useState(initialState.signedIn);
useEffect(() => {
fbInit();
})
const testLog = () => {
console.log("TAG Test Log Func")
}
return (
<FirebaseContext.Provider value={{isUserSignedIn, setIsUserSignedIn}}>
{children}
</FirebaseContext.Provider>
);
}
This is where I am trying to use the values (I am trying to log the values when I press the Button)
import { useNavigation } from '#react-navigation/native';
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import {Button, Card, TextInput} from 'react-native-paper';
import { FirebaseContext } from '../../context/FirebaseContext';
import React, {useContext, useEffect, useState } from 'react';
const initialUserState = {
userName: 'Nicole Lopez',
password: '1001008888',
}
export default function LoginScreen() {
const [disabled, setDisabled] = useState(false);
const [userState, setUserState] = useState(initialUserState);
const { fbContext } = useContext(FirebaseContext);
const navigation = useNavigation();
const onInputChange = (field, value) => {
setUserState({
...userState,
[field]: value
})
}
useEffect(() => {
setDisabled(userState.userName.length === 0 || userState.password.length === 0);
}, [userState.userName, userState.password])
return (
<View style={styles.container}>
<Card style={styles.card}>
<TextInput
mode="outlined"
label="Förnamn & Efternman"
defaultValue={userState.userName}
onChangeText={text => onInputChange("username", text)}
right={<TextInput.Icon name="account" onPress={() => {
}}/>}
style={styles.textInput}/>
<TextInput
mode="outlined"
label="Anställningsnummer 100100xxxx"
defaultValue={userState.password}
right={<TextInput.Icon name="lock"/>}
onChangeText={text => onInputChange("password", text)}
style={styles.textInput}/>
</Card>
<View style={styles.buttonRow}>
<Button
color={disabled ? "gray" : undefined}
disabled={disabled}
mode={'contained'}
icon={'login'}
onPress={() => {
console.log("TAG isUserSignedIn: " + fbContext?.isuserSignedIn)
//fbContext?.testLog()
//console.log("TAG LOGIN BTN PRESSED")
//navigation.navigate('HomeScreen')
}}>Login</Button>
</View>
</View>
);
}
This is my App.js:
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import {StackScreens} from './src/helpers/types';
import { NavigationContainer, useNavigationContainerRef } from '#react-navigation/native';
import LoginScreen from './src/screens/LoginScreen/LoginScreen';
import HomeScreen from './src/screens/HomeScreen/HomeScreen';
import {doc, getFirestore, onSnapshot, setDoc, Unsubscribe as UnsubscribeFS} from 'firebase/firestore';
import { FirebaseContextProvider, FirebaseContext } from './src/context/FirebaseContext';
import { useContext } from 'react';
//import { navigationRef } from './RootNavigation';
//const userDocument = firestore().collection("users").doc('Cstl3bA9xwwH3UwHZJhA').get();
const Stack = createNativeStackNavigator();
export default function App() {
return (
<FirebaseContextProvider>
<Content />
</FirebaseContextProvider>
);
}
export const Content = () => {
const navigationRef = useNavigationContainerRef();
const firebaseContext = useContext({FirebaseContext});
return (
<NavigationContainer ref={navigationRef}>
<Stack.Navigator initialRouteName="LoginScreen">
<Stack.Screen name="LoginScreen" component={LoginScreen} />
<Stack.Screen name="HomeScreen" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
Don't know what I have missed, I have installed the packages, I have tried to log different values but all seem to be undefined :/
I believe it is undefined because you're trying to destructure the context value, maybe
const { fbContext } = useContext(FirebaseContext);
should be
const fbContext = useContext(FirebaseContext);
For someone getting undefined from context, check on which level you placed your context provider. If you want to use context in a component you should wrap this component in a context provider outside of this component!
Incorrect way
const Component = () => {
const { value1, value2 } = useContext(MyContext); //here context value will be undefined
return (
<ContextProvider>
//Component content
</ContextProvider>
)
}
Correct way
const ComponentA = () => {
const { value1, value2 } = useContext(MyContext);
return(//Component A content)
}
const ComponentB = () => {
return(
<ContextProvider>
<ComponentA/>
</ContextProvider>
)
}

Not sure how to integrate function within useEffect

I am trying to call a function within useEffect, how would I mount this function within useEffect, I am not sure?
Initially useEffect is included as the following-
useEffect(() => {
CognitensorEndpoints.getDashboardList({
dispatchReducer: dispatchDashboards,
});
CognitensorEndpoints.getList({
dispatchReducer: dispatchDashboards,
});
},[]);
Then when I include function within useEffect, it returns error - 'Cannot read property 'filter' of undefined' -
useEffect(() => {
console.log('abcd');
setLoading();
CognitensorEndpoints.getDashboardList({
dispatchReducer: dispatchDashboards,
});
CognitensorEndpoints.getList({
dispatchReducer: dispatchDashboards,
});
},[]);
How do I correctly include the 'setLoading()' function within useEffect?
Here's the full app code-
import React, { useState, useEffect, useReducer } from 'react';
import { View, Text, StyleSheet, FlatList, ActivityIndicator, Keyboard, Button } from 'react-native';
import { Searchbar } from 'react-native-paper';
import { theme } from '../theme';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { apiStateReducer } from '../reducers/ApiStateReducer';
import CognitensorEndpoints from '../services/network/CognitensorEndpoints';
import DefaultView from '../components/default/DefaultView';
import DashboardListCard from '../components/DashboardListCard';
import DashboardHeader from '../components/DashboardHeader';
import DashboardGridCard from '../components/DashboardGridCard';
import {
NavigationContainer,
useFocusEffect,
} from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
const AppHeader = ({
scene,
previous,
navigation,
searchIconVisible = false,
item,
index,
onPress
}) => {
const [dashboards, dispatchDashboards] = useReducer(apiStateReducer, {
data: [],
isLoading: true,
isError: false,
});
const [gridView, setGridView] = useState(false);
const toggleGridView = () => {
setGridView(!gridView);
};
const [filtered, setFiltered] = useState([]);
const setLoading = () => {
const messages = dashboards.data.message.filter((item) => {
const title = item.dashboardTitle || item.dashboardName;
return title.toLowerCase();
});
setFiltered(messages);
console.log(filtered);
};
const dropShadowStyle = styles.dropShadow;
const toggleSearchVisibility = () => {
navigation.navigate('Search');
};
useEffect(() => {
console.log(abcd);
setLoading();
CognitensorEndpoints.getDashboardList({
dispatchReducer: dispatchDashboards,
});
CognitensorEndpoints.getList({
dispatchReducer: dispatchDashboards,
});
},[]);
return (
<>
<View style={styles.header}>
<View style={styles.headerLeftIcon}>
<TouchableOpacity onPress={navigation.pop}>
{previous ? (
<MaterialIcons
name="chevron-left"
size={24}
style={styles.visible}
/>
) : (
<MaterialIcons
name="chevron-left"
size={24}
style={styles.invisible}
/>
)}
</TouchableOpacity>
</View>
{filtered.map(item => (
<Text style={styles.headerText}>
{item.dashboardTitle}
</Text>
))}
<View style={styles.headerRightIconContainer}>
{searchIconVisible ? (
<TouchableOpacity
style={[styles.headerRightIcon, dropShadowStyle]}
onPress={toggleSearchVisibility}>
<MaterialIcons name="search" size={24} style={styles.visible} />
</TouchableOpacity>
) : (
<View style={styles.invisible} />
)}
</View>
</View>
</>
);
};
Use setfilters in useEffect. it will be called when dashboards value changed.
useEffect(() => {
console.log(dashboards);
if(dashboards.data.message) {
const messages = dashboards.data.message.filter((item) => {
const title = item.dashboardTitle || item.dashboardName;
return title.toLowerCase();
});
setFiltered(messages);
console.log(filtered);
}
},[dashboards]);
import React, { useState, useEffect, useReducer } from 'react';
import { View, Text, StyleSheet, FlatList, ActivityIndicator, Keyboard, Button } from 'react-native';
import { Searchbar } from 'react-native-paper';
import { theme } from '../theme';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { apiStateReducer } from '../reducers/ApiStateReducer';
import CognitensorEndpoints from '../services/network/CognitensorEndpoints';
import DefaultView from '../components/default/DefaultView';
import DashboardListCard from '../components/DashboardListCard';
import DashboardHeader from '../components/DashboardHeader';
import DashboardGridCard from '../components/DashboardGridCard';
import {
NavigationContainer,
useFocusEffect,
} from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
const AppHeader = ({
scene,
previous,
navigation,
searchIconVisible = false,
item,
index,
onPress
}) => {
const [dashboards, dispatchDashboards] = useReducer(apiStateReducer, {
data: [],
isLoading: true,
isError: false,
});
const [gridView, setGridView] = useState(false);
const toggleGridView = () => {
setGridView(!gridView);
};
const [filtered, setFiltered] = useState([]);
const setLoading = () => {
const messages = dashboards.data.message.filter((item) => {
const title = item.dashboardTitle || item.dashboardName;
return title.toLowerCase();
});
setFiltered(messages);
console.log(filtered);
};
const dropShadowStyle = styles.dropShadow;
const toggleSearchVisibility = () => {
navigation.navigate('Search');
};
useEffect(() => {
CognitensorEndpoints.getDashboardList({
dispatchReducer: dispatchDashboards,
});
CognitensorEndpoints.getList({
dispatchReducer: dispatchDashboards,
});
},[]);
useEffect(()={ if(dashboards.data.length > 0) { setLoading(); } },[dashboards]);
return (
<>
<View style={styles.header}>
<View style={styles.headerLeftIcon}>
<TouchableOpacity onPress={navigation.pop}>
{previous ? (
<MaterialIcons
name="chevron-left"
size={24}
style={styles.visible}
/>
) : (
<MaterialIcons
name="chevron-left"
size={24}
style={styles.invisible}
/>
)}
</TouchableOpacity>
</View>
{filtered.map(item => (
<Text style={styles.headerText}>
{item.dashboardTitle}
</Text>
))}
<View style={styles.headerRightIconContainer}>
{searchIconVisible ? (
<TouchableOpacity
style={[styles.headerRightIcon, dropShadowStyle]}
onPress={toggleSearchVisibility}>
<MaterialIcons name="search" size={24} style={styles.visible} />
</TouchableOpacity>
) : (
<View style={styles.invisible} />
)}
</View>
</View>
</>
);
};

ERROR: Touchable child must either be native or forward setNativeProps to a native component

I am currently doing ReactNative course from coursera and the course is 4 years old and i am facing this error: Touchable child must either be native or forward setNativeProps to a native component.
I've no idea what this is. It will be greatly helpful if someone will help me.Adding files details as well:
App.js
import React from 'react';
import Main from './components/MainComponent';
export default class App extends React.Component {
render() {
return (
<Main />
);
}
}
MainComponent.js
import React, { Component } from 'react';
import Menu from './MenuComponent';
import { DISHES } from '../shared/dishes';
import Dishdetail from './DishdetailComponent';
import { View } from 'react-native';
class Main extends Component {
constructor(props) {
super(props);
this.state = {
dishes: DISHES,
selectedDish: null,
};
}
onDishSelect(dishId) {
this.setState({selectedDish: dishId})
}
render() {
return (
<View style={{flex:1}}>
<Menu dishes={this.state.dishes} onPress={(dishId) => this.onDishSelect(dishId)} />
<Dishdetail dish={this.state.dishes.filter((dish) => dish.id === this.state.selectedDish)[0]} />
</View>
);
}
}
export default Main;
MenuComponent.js
import React from 'react';
import { View, FlatList } from 'react-native';
import { ListItem } from 'react-native-elements';
function Menu(props) {
const renderMenuItem = ({item, index}) => {
return (
<View>
<ListItem
key={index}
title={item.name}
subtitle={item.description}
hideChevron={true}
onPress={() => props.onPress(item.id)}
leftAvatar={{ source: require('./images/uthappizza.png')}}
/>
</View>
);
};
return (
<View>
<FlatList
data={props.dishes}
renderItem={renderMenuItem}
keyExtractor={item => item.id.toString()}
/>
</View>
);
}
export default Menu;
Dishdetailcomponent.js
import React from 'react';
import { Text, View } from 'react-native';
import { Card } from 'react-native-elements';
function Dishdetail(props) {
return(
<View >
<RenderDish dish={props.dish} />
</View>
);
}
function RenderDish(props) {
const dish = props.dish;
if (dish != null) {
return(
<View>
<Card
featuredTitle={dish.name}
image={require('./images/uthappizza.png')}>
<Text style={{margin: 10}}>
{dish.description}
</Text>
</Card>
</View>
);
}
else {
return(<View></View>);
}
}
export default Dishdetail;
Help will be appreciated!!
Thanks
I had same issue some days before. Quickfix for this issue.
import TouchableOpacity form 'react-native';
Add following in the MenuComponent.js
<ListItem
Component={TouchableOpacity}
key={item.id}
title={item.name}
subtitle={item.description}
hideChevron={true}
onPress={() => props.onPress(item.id)}
leftAvatar={{ source: require('./images/uthappizza.png')}}
/>
and run the program again. This will fix your problem.

Call component through function React Native

I'm developing a component to publish it in npm, but I'd like to call my component using a method instead of a tag.
Example:
myComponent.js
import React from 'react'
import { View, Text } from 'react-native'
export const showComponent = () => {
// this would be the function that I user to call my component down
}
const myComponent = (props) => {
return(
<View>
<Text>Oi</Text>
</View>
)
}
App.js
import React from 'react'
import { View, Text, TouchableOpacity } from 'react-native'
import { showComponent } from 'my-component'
const App = () => {
return(
<View>
<TouchableOpacity onPress={() => showComponent()}>
<Text>Home</Text>
</TouchableOpacity>
</View>
)
}
export defaul App
the idea is that when calling the showComponent function I show my component, and when I call, for example, the hide function, I close my component.
You can do it using a single class export:
import * as React from 'react';
export default class MyComponent extends React.Component {
state = {
isOpen: false,
};
open = () => {
this.setState({ isOpen: true });
};
close = () => {
this.setState({ isOpen: true });
};
render() {
const { isOpen } = this.state;
return !isOpen ? null : (
<View>
<Text>Oi</Text>
</View>
);
}
}
And you use it like so:
<MyComponent ref={(x) => this.myComponent = x)} />
And you open it like so:
this.myComponent.open();
I see in a comment above you want to call the component with a redux action, so you should call your redux action in that on click, but the component you want to show/hide needs to be linked to a redux state variable. Then in your jsx you'd have:
<View>
<TouchableOpacity onPress={() => showComponent()}>
<Text>Home</Text>
</TouchableOpacity>
{reduxBoolean && <MyComponent />}
</View>
import React from 'react'
import { View, Text} from 'react-native'
const example = (props) => {
return (
<View>
<Text>Hello</Text>
</View>
)
}
// props
import React from 'react'
import { View, Text} from 'react-native'
const examples = () => {
return(
<View>
<Text><example/></Text>
</View>
)
}
and print is : Hello

How To Get Props in another Screen in react navigation?

I have an issue with react-navigation in passing the props to another screen,
I need to pass some props to Detail screen when the user presses one of the List Places I need to push screen with some details about the place like a Name of place and Image of place,
Errors :
this is my Code
Reducer
import { ADD_PLACE, DELETE_PLACE } from "../actions/actionTypes";
const initialState = {
places: []
};
import placeImage from "../../assets/img.jpg";
const reducer = (state = initialState, action) => {
switch (action.type) {
case ADD_PLACE:
return {
...state,
places: state.places.concat({
key: Math.random(),
name: action.placeName,
// image: placeImage,
image: {
uri:
"https://images.unsplash.com/photo-1530009078773-9bf8a2f270c6?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80"
}
})
};
case DELETE_PLACE:
return {
...state,
places: state.places.filter(place => {
return place.key !== state.selectedPlace.key;
})
};
default:
return state;
}
};
export default reducer;
Place List Component
import React from "react";
import { FlatList, StyleSheet, ScrollView } from "react-native";
import ListItem from "../ListItem/ListItem";
const PlaceList = props => {
return (
<FlatList
style={styles.listContainer}
data={props.places}
renderItem={info => (
<ListItem
placeName={info.item.name}
placeImage={info.item.image}
onItemPressed={() => props.onItemSelected(info.item.key)}
/>
)}
keyExtractor={index => String(index)}
/>
);
};
export default PlaceList;
Find Place Screen
import React, { Component } from "react";
import { View, Text } from "react-native";
import { connect } from "react-redux";
import { StackActions } from "react-navigation";
import PlaceList from "../../Components/PlaceList/PlaceList";
class FindPlaceScreen extends Component {
constructor() {
super();
}
itemSelectedHandler = key => {
const selPlace = this.props.places.find(place => {
return place.key === key;
});
this.props.navigation.push("PlaceDetail", {
selectedPlace: selPlace,
name: selPlace.name,
image: selPlace.image
});
};
render() {
return (
<View>
<PlaceList
places={this.props.places}
onItemSelected={this.itemSelectedHandler}
/>
</View>
);
}
}
const mapStateToProps = state => {
return {
places: state.places.places
};
};
export default connect(mapStateToProps)(FindPlaceScreen);
Place Details Screen
import React, { Component } from "react";
import { View, Text, Image, TouchableOpacity, StyleSheet } from "react-native";
import Icon from "react-native-vector-icons/Ionicons";
class PlaceDetail extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View style={styles.modalContainer}>
<View>
<Image
source={this.props.navigation.state.params.image}
style={styles.placeImage}
/>
<Text style={styles.placeName}>
{this.props.navigation.state.params.namePlace}
</Text>
</View>
<View>
<TouchableOpacity onPress={props.onItemDeleted}>
<View style={styles.deleteButton}>
<Icon size={30} name="ios-trash" color="red" />
</View>
</TouchableOpacity>
<TouchableOpacity onPress={props.onModalClosed}>
<View style={styles.deleteButton}>
<Icon size={30} name="ios-close" color="red" />
</View>
</TouchableOpacity>
</View>
</View>
);
}
}
export default PlaceDetail;
You need to use react-native-navigation v2 for the find place screen
itemSelectedHandler = key => {
const selPlace = this.props.places.find(place => {
return place.key === key;
});
Navigation.push(this.props.componentId, {
component: {
name: 'PlaceDetail',
options: {
topBar: {
title: {
text: selPlace.name
}
}
},
passProps: {
selectedPlace: selPlace
}
}
});
};
make sure you import { Navigation } from "react-native-navigation";
Your PlaceDetail has some error
<TouchableOpacity onPress={props.onItemDeleted}>
<TouchableOpacity onPress={props.onModalClosed}>
Change props to this.props
<TouchableOpacity onPress={this.props.onItemDeleted}>
<TouchableOpacity onPress={this.props.onModalClosed}>
But I don't see onItemDeleted and onModalClosed anywhere, don't forget to pass those to PlaceDetail via props as well :)

Categories