Identifier has already been declared react native - react-native

So I have created a simple react-native following the Coursera lectures.
My Menu component just holds a list of recipes and displays them on the device.
import React, { Component } from 'react';
import { View, FlatList } from 'react-native';
import { ListItem } from 'react-native-elements';
function Menu(props){
const renderMenuItem = ({item, index}) => {
return(
<ListItem
key={index}
title={item.name}
subtitle={item.description}
hideChevron={true}
onPress={() => props.onPress(item.id)}
leftAvatar={{ source: require('./images/uthappizza.png')}}
/>
);
}
return(
<FlatList
data={props.dishes}
renderItem={renderMenuItem}
keyExtractor={item => item.id.toString()}
/>
)
}
export default Menu;
Next, there is the DishdetailComponent which renders the details of each dish.
import React from 'react';
import { Text, View } from 'react-native';
import { Card } from 'react-native-elements';
function RenderDish(props) {
const dish = props.dish;
if (dish != null) {
return(
<Card
featuredTitle={dish.name}
image={require('./images/uthappizza.png')}>
<Text style={{margin: 10}}>
{dish.description}
</Text>
</Card>
);
}
else {
return(<View></View>);
}
}
function Dishdetail(props) {
return(<RenderDish dish={props.dish} />);
}
export default Dishdetail;
And finally, I have the MainComponent which is like the top component holding the two previous components.
import { View } from 'react-native';
import { DISHES } from '../shared/dishes';
import Dishdetail from './DishdetailComponent';
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;
When I run the app I get this
Did I miss something? Here is my repo if you want to have a closer look.

Few moments here:
1) Seems you forgot to import the Menu component at the top of imports
2) You simply have a typo in the import of DishdetailComponent
Just paste these lines instead of yours
import { View } from "react-native";
import { DISHES } from "../shared/dishes";
import Dishdetail from "./DishDetailComponent";
import Menu from "./MenuComponent";
Also, sometimes bunder crashes and don't reload.
To fix this I would suggest using
yarn start --reset-cache command (but don't forget to kill previous Metro Bundler instance) :)

Related

Navigation.getParam is undefined while trying to pass function as parameter

I'm trying to use a function from my Main component in my details component which I user react navigation to navigate to and I want to save some changes in detail screen in my main component
//Main.js
import React from 'react';
import {
StyleSheet ,
Text,
View,
TextInput,
ScrollView,
TouchableOpacity,
KeyboardAvoidingView,
AsyncStorage
} from 'react-native'
import Note from './Note'
import { createStackNavigator, createAppContainer } from "react-navigation";
import Details from './Details';
export default class Main extends React.Component {
static navigationOptions = {
title: 'To do list',
headerStyle: {
backgroundColor: '#f4511e',
},
};
constructor(props){
super(props);
this.state = {
noteArray: [],
noteText: ''
};
}
render() {
let notes = this.state.noteArray.map((val,key) => {
return <Note key={key} keyval={key} val={val}
goToDetailPage= {() => this.goToNoteDetail(key)}
/>
});
const { navigation } = this.props;
return(
<View style={styles.container}>
<ScrollView style={styles.scrollContainer}>
{notes}
</ScrollView>
<Details saveEdit={this.saveEdit} />
</View>
);
}
goToNoteDetail=(key)=>{
this.props.navigation.navigate('DetailsScreen', {
selectedTask: this.state.noteArray[key],
saveEdit: this.saveEdit
});
}
saveEdit = (editedTask,dueDate) => {
this.state.noteArray.push({
'creationDate': editedTask['creationDate'],
'taskName': editedTask['taskName'],
'dueDate': dueDate
});
this.setState({noteArray:this.state.noteArray})
this.saveUserTasks(this.state.noteArray)
}
this.setState({noteArray:this.state.noteArray})
this.saveUserTasks(this.state.noteArray)
}
}
Then I try to use it as prop in my Detail.js
import React from 'react';
import {
StyleSheet ,
Text,
View,
TextInput,
Button,
TouchableOpacity,
} from 'react-native'
import { createStackNavigator, createAppContainer } from "react-navigation";
export default class Details extends React.Component {
constructor(props){
super(props);
this.state = {
dueDate = ''
}
}
static navigationOptions = {
headerStyle: {
backgroundColor: '#f4511e',
},
};
componentDidMount = () => {
this.getUserTasks()
}
render() {
const { navigation } = this.props;
const selectedTask = navigation.getParam('selectedTask', 'task');
var { saveEdit} = this.props;
return(
<View key={this.props.keyval} style={styles.container}>
<View style = { styles.info}>
<Text style= {styles.labelStyle}> Due date:
</Text>
<TextInput
onChangeText={(dueData) => this.setState({dueData})}
style={styles.textInput}
placeholder= {selectedTask['dueDate']}
placeholderTextColor='gray'
underlineColorAndroid = 'transparent'
>
</TextInput>
</View>
<TouchableOpacity onPress={this.props.saveEdit(selectedTask, this.state.dueDate)} style={styles.saveButton}>
<Text style={styles.saveButtonText}> save </Text>
</TouchableOpacity>
</View>
);
}
}
I searched a lot to find the solution and I tried many of them but get different undefined errors. This is not what I did in the first place but when I search I found this solution here. And I know it causes lots of issues.
I want to know how can I manage to access to main method from details and pass parameters to it or how can I manage to use main props in my details component
If you are using react-navigation 5, params is no longer under the navigation object but under route object. This is the link to the sample code:
https://reactnavigation.org/docs/params
Solution
<Details saveEdit={this.saveEdit} />
to
<Details navigation={this.props.navigation} saveEdit={this.saveEdit} />
render() {
return(
<View style={styles.container}>
<ScrollView style={styles.scrollContainer}>
{notes}
</ScrollView>
<Details navigation={this.props.navigation} saveEdit={this.saveEdit} />
</View>
);
}
Why?
You are using your Details component in Main screen. So you need to give navigation to Details's props from your Main to use navigation props in Details component.
Because your Details component is not the screen component registered in your navigator(router).
I tried to run your code on my machine but it seems you have too many syntax error in your code (maybe because of copy pasta?)
but it seems you should change
<TouchableOpacity onPress={this.props.saveEdit(selectedTask, this.state.dueDate)}
in Detals.js to
<TouchableOpacity onPress={this.props.navigation.getParams('saveEdit')(selectedTask, this.state.dueDate)}
for clarification this worked for me
in MainPage.js
_test(){
console.log('test');
}
.
.
.
<ActionButton
buttonColor="rgba(231,76,60,1)"
onPress={() => NavigationService.navigate('AddNewSession', {test: this._test})}>
</ActionButton>
and in AddNewSession.js
componentDidMount()
let test = this.props.navigation.getParam('test');
test();
}
There are many mistakes within your codes. First of all you are importing the navigation build-in function {createStackNavigator} in all your files, Main.js and Details.js :
import { createStackNavigator, createAppContainer } from
"react-navigation";
That make me think that you didn't know how the stack navigation or navigation in general functions in react native. You should have a file that handles your routes configuration, let call it MyNavigation.js and then define the routes 'Main' and 'details' in MyNavigations,js. It's only inside MyNavigation.js that you can import "createStackNavigator". Then you will define your functions to move between the screens "Main" and "detail". Those functions will be passed as props to the routes when moving between one another. The overall action wihtin MyNavigation.js will look like:
import React from 'react';
import { createStackNavigator } from '#react-navigation/stack';
import { NavigationContainer } from '#react-navigation/native';
import Main from './Main';
import Detail from './Detail';
const Stack = createStackNavigator();
function goToDetailFromMainScreen(){
return(this.props.navigation.navigate('switch2'));
}
function DetailSaves(){
return(//your code here to save details);
}
//Here you pass the functions to Main Component to handele Detail componets
's actions
function switch1(){
return(<Main GoToDetails={() => this.goTodetailFromMainScreen()} paramsForDetailActions={() => this.detailSaves()} />)
}
function switch2(){
return(<Details />)
}
export default function MyNavigation() {
return(
<NavigationContainer>
<Stack.Navigator initialRouteName='switch1'>
<Stack.Screen name='switch1' options={{header:()=>null}} component={Main} />
<Stack.Screen name='switch2' options={{headerTitle:"Detail"}} component={Detail} />
</Stack.Navigator>
</NavigationContainer>
)
}
Now inside Main.js you check the props functions passed to it from MyNavigation.js:
// Main.js
constructor(props){
super(props);
}
goToDetails = () => {
this.props.onPress?.();
}
paramsForDetailActions= () => {
this.props.onPress?.();
}

"Cannot add a child that doesn't have YogaNode to a parent without a measure function "

While building a react-native application for Android I am getting the error
Cannot add a child that doesn't have Yoga Node to a parent without a
measure function
I tried with both remote debugger on and off but the problem persists.
Pasting my Component function as below.
import React, { Component } from 'react';
import { Text, TouchableWithoutFeedback, View } from 'react-native';
import { connect } from 'react-redux';
import { CardSection } from './common';
import * as actions from '../actions';
class ListItem extends Component {
render() {
const { title, id } = this.props.library;
const { titleStyle } = styles;
return (
<TouchableWithoutFeedback
onPress ={() => this.props.selectLibrary(id)}
>
<View> /* Using View as more then one card section is used */
<CardSection>
<Text style={titleStyle} >
{title}
</Text>
</CardSection>
</View>
</TouchableWithoutFeedback>
)
}
}
const styles = {
titleStyle: {
fontSize:18,
paddingLeft:10
}
};
export default connect(null, actions)(ListItem);
The problem is resolved once I moved my comments in front of the View tag to other location ( for example, before return statement)

Render list item using FlatList in React Native and Firebase

Very new to react-native. I am not sure how data is passed into the Flatlist and how to render it. I am passing in the Restaurants array from firebase database to this.restaurantRef. listenForRestaurants is called when first rendered to push all the referenced items into an array called restaurants. Not quite sure how I should put the logic for rendering the list of restaurants from firebase database.
import React from 'react'
import {Component} from 'react'
import {
ScrollView,
Text,
FlatList,
} from 'react-native'
import firebase from '../firebase'
import ListItem from './ListItem'
export default class Location extends Component {
constructor(props){
super(props)
this.restaurantRef = firebase.database().ref().
child('Restaurants')
}
listenForRestaurants(restaurantRef) {
restaurantRef.on('value', (snapshot) => {
var restaurants = [];
snapshot.forEach((child) => {
restaurants.push({
name: child.val().name,
_key: child.val().key
})
})
})
}
componentDidMount(){
this.listenForRestaurants(this.restaurantRef)
}
_renderItem(item){
return(
<ListItem item={item} onPress={() => {}} />
)
}
render(){
return(
<ScrollView>
<FlatList
data={this.restaurantRef}
renderItem={this._renderItem}
/>
</ScrollView>
)
}
}
//This the ListItem component
import React, {Component} from 'react'
import {
View,
TouchableHighlight,
Text,
} from 'react-native';
export default class ListItem extends Component {
render() {
return (
<TouchableHighlight onPress={this.props.onPress}>
<View>
<Text>{this.props.item.name}</Text>
</View>
</TouchableHighlight>
);
}
}

Disable console log in react navigation

I'm using react navigation for my app development. When i run log-android, it keeps logging something like this.
Navigation Dispatch: Action: {...}, New State: {...}
which is from createNavigationContainer.js line 150.
I've run through github and document said it could be done by by setting onNavigationStateChange={null} on a top-level navigator.
How can i achieve this by setting onNavigationStateChange={null} and where should i set it?
I've try to set like below, but it the page will not be able to redirect to other page.
export default () => {
<App onNavigationStateChange={null} />
}
Below are my app.js code
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View } from 'react-native';
import { StackNavigator,DrawerNavigator } from 'react-navigation';
import DrawerContent from './components/drawer/drawerContent.js';
import News from './components/news/home.js';
const drawNavigation = DrawerNavigator(
{
Home : {
screen : News ,
navigationOptions : {
header : null
}
}
},
{
contentComponent: props => <DrawerContent {...props} />
}
)
const StackNavigation = StackNavigator({
Home : { screen : drawNavigation,
navigationOptions: {
header: null
}
}
});
export default StackNavigation;
This is my drawerContent.js
import React, {Component} from 'react'
import {View,Text, StyleSheet,
TouchableNativeFeedback,
TouchableOpacity,
TouchableHighlight
} from 'react-native'
import { DrawerItems, DrawerView } from 'react-navigation';
import Icon from 'react-native-vector-icons/Octicons';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
class DrawerContent extends Component {
constructor(props){
super(props);
console.log('DrawerContent|testtttttt');
}
render(){
return (
<View style={styles.container}>
<Text>Hi darren</Text>
<TouchableOpacity style={{ marginBottom:5 }} onPress={() => this.props.navigation.navigate('RegistrationScreen') } >
<View style={styles.nonIconButton}>
<Text style={{ color: 'black',fontSize: 13 }} >Sign Up</Text>
</View>
</TouchableOpacity>
<Text>Hi darren</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default DrawerContent;
First, make sure you are using the latest release of react-navigation as the comment noting that the fix was committed is fairly recent.
Based on your code example, to disable logging for all navigation state changes, you would want to replace this code:
export default StackNavigation;
with:
export default () => (
<StackNavigation onNavigationStateChange={null} />
);
as StackNavigation appears to be your root navigator.
React navigation is great, but this logging is really bad. Solution
const AppNavigator = StackNavigator(SomeAppRouteConfigs);
class App extends React.Component {
render() {
return (
<AppNavigator onNavigationStateChange={null} />
);
}
}

React native got blank screen

I'm new to react-native, and I'm trying to use a navigator to switch between different scenes. However, when the simulator runs, instead of printing an error, I just got an empty, blank, white screen that shows nothing expect the remaining battery, the time, and the wifi signal. I checked my code many times and cannot find an error. Can someone help me on this?
This is my index.ios.js file:
import React, { Component } from 'react';
import {
AppRegistry,
Text,
View,
Navigator
} from 'react-native';
import Chatroom from './Views/Chatroom';
import Chat from './Views/Chat';
class goals extends Component{
render(){
return(
<Navigator
initialRoute={{screen: 'Chatroom'}}
renderScene={(route, nav) => {return this.renderScene(route.screen)}}
/>
)
}
renderScene(route,nav) {
switch (route.screen) {
case 'Chatroom':
return <Chatroom navigator={nav} />
case 'Chat':
return <Chat navigator={nav} />
}
}
}
AppRegistry.registerComponent('goals', () => goals);
This is my Chat.js file:
import React, { Component } from 'react';
import { View, Text, TouchableHighlight } from 'react-native';
export default class Chat extends Component {
render() {
return (
<View>
<Text>This is chat</Text>
<TouchableHighlight onPress={this.gochatroom.bind(this)}>
<Text>Go to chatroom</Text>
</TouchableHighlight>
</View>
)
}
gochatroom() {
this.props.navigator.push({ screen: 'Chatroom' });
}
}
This is my Chatroom.js file:
import React, { Component } from 'react';
import { View, Text, TouchableHighlight } from 'react-native';
export default class Chatroom extends Component {
render() {
return (
<View>
<Text>This is chatroom</Text>
<TouchableHighlight onPress={this.gochat.bind(this)}>
<Text>Go to chat</Text>
</TouchableHighlight>
</View>
)
}
gochat() {
this.props.navigator.push({ screen: 'Chat' });
}
}
You aren't passing the right arguments to renderScene. The following should work better:
renderScene={(route, nav) => this.renderScene(route, nav)}