Navigate Issue From a ListView - javascript

I have 2 listview in my homepage (TodoDetail.js and TodoDetailChecked.js) and there is TouchableOpacity's in this listview's rows.. When I click this TouchableOpacity, I want to go to Profile.js page.
But the problem is when I click, it can not find props.navigation.navigate.
I tried to catch logs in componentDidMount but nothing about navigate.
componentDidMount() {
console.log(this.props);
}
Please help me...
Here is the code;
TodoDetail.js
import React, { Component } from 'react';
import { Card, Icon } from 'react-native-elements';
// import Checkbox from '../components/Checkbox';
import { Text, View, TouchableOpacity } from 'react-native';
import * as firebase from 'firebase';
import {
Menu,
MenuOptions,
MenuOption,
MenuTrigger,
} from 'react-native-popup-menu';
class TodoDetail extends Component {
componentDidMount() {
console.log(this.props.navigation.navigate('TodoDetail'));
}
clickText() {
const { todo } = this.props.todos;
// const { navigate } = this.props.navigation;
return (
<TouchableOpacity onPress={this.seeDetail.bind(this)} >
<Text numberOfLines={1}> {todo} </Text>
</TouchableOpacity>
);
}
seeDetail() {
const { navigate } = this.props.navigation;
navigate("Profile", { name: "Jane" });
console.log('click');
}
render() {
//Serverdan çekilenler
const uid = this.props.todos.uid;
const success = this.props.todos.success;
//Tarih olayları
const date = new Date();
const day = date.getDate();
const tomorrow = day + 1;
const year = date.getFullYear();
const month = date.getMonth();
//Style tanımlama
const { container, iconContainer, subContainer } = styles;
if (success === 0) {
return (
<Card>
<View style={container}>
<View style={iconContainer}>
<TouchableOpacity onPress={() => firebase.database().ref(`todos/personal/${uid}/success`).set(1)} >
<Icon name='check-box-outline-blank' />
</TouchableOpacity>
<View style={subContainer}>
{this.clickText()}
</View>
<View style={iconContainer}>
<Menu>
<MenuTrigger>
<Icon name='keyboard-arrow-down' />
</MenuTrigger>
<MenuOptions>
<MenuOption onSelect={() => firebase.database().ref(`todos/personal/${uid}/date`).set({ day, year, month })} >
<Text style={{ color: 'black' }} > Son Tarihi Bugün </Text>
</MenuOption>
<MenuOption onSelect={() => firebase.database().ref(`todos/personal/${uid}/date`).set({ day: tomorrow, year, month })} >
<Text style={{ color: 'black' }} > Son Tarihi Yarın </Text>
</MenuOption>
<MenuOption onSelect={() => firebase.database().ref(`todos/personal/${uid}/date`).remove()} >
<Text style={{ color: 'black' }} > Son Tarihi Kaldır </Text>
</MenuOption>
<MenuOption onSelect={() => firebase.database().ref(`todos/personal/${uid}`).remove()} >
<Text style={{ color: 'red' }} > Yapılacak İşi Sil </Text>
</MenuOption>
</MenuOptions>
</Menu>
</View>
</View>
</View>
</Card>
);
} else
if (success === 1) {
return (
null
);
}
}
}
Todolist.js
createDataSource({ studentsArray }) {
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
});
this.dataSource = ds.cloneWithRows(studentsArray.reverse());
}
changeScreen() {
this.setState({ screenSize: false });
}
changeScreenBack() {
this.setState({ screenSize: true });
}
renderRow(todos) {
return <TodoDetail todos={todos} />;
}
renderRow2(todos) {
return <TodoDetailChecked todos={todos} />;
}
render() {
// const { navigate } = this.props.navigation;
const { container, inputContainer, inputText } = styles;
if (!this.state.screenSize) {
return (
<View style={container} >
<View style={inputContainer} >
<Icon name={'add'} />
<TextInput
style={inputText}
underlineColorAndroid='transparent'
placeholder="Yapılacak iş ekle..."
placeholderTextColor="#FFFFFF"
value={this.props.todo}
onChangeText={todo => this.props.todoChanged(todo)}
/>
<Button
onPress={this.addToDo.bind(this)}
title="Ekle"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
</View>
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<ListView
enableEmptySections
dataSource={this.dataSource}
renderRow={this.renderRow}
/>
</View>
<View style={{ flex: 1 }}>
<View style={{ height: 1, backgroundColor: 'gray' }} />
<ListView
enableEmptySections
dataSource={this.dataSource}
renderRow={this.renderRow2}
/>
</View>
</View>
<Button
onPress={this.changeScreenBack.bind(this)}
title="Tamamlananları Gizle"
color="#841584"
/>
</View>
);
} else
if (this.state.screenSize) {
return (
<View style={container} >
<View style={inputContainer} >
<Icon name={'add'} />
<TextInput
style={inputText}
underlineColorAndroid='transparent'
placeholder="Yapılacak iş ekle..."
placeholderTextColor="#FFFFFF"
value={this.props.todo}
onChangeText={todo => this.props.todoChanged(todo)}
/>
<Button
onPress={this.addToDo.bind(this)}
title="Ekle"
color="#841584"
/>
</View>
<View style={{ flex: 1 }}>
<ListView
enableEmptySections
dataSource={this.dataSource}
renderRow={this.renderRow}
/>
<Button
onPress={this.changeScreen.bind(this)}
title="Tamamlananları Göster"
color="#841584"
/>
</View>
</View>
);
}
}
}
Router.js
import { StackNavigator } from 'react-navigation';
import Todolist from './src/Todolist';
import Profile from './src/Profile';
import TodoDetail from './components/TodoDetail';
import TodoDetailChecked from './components/TodoDetailChecked';
import TodoPage from './components/TodoPage';
const Router = StackNavigator({
Todolist: { screen: Todolist },
TodoDetail: { screen: TodoDetail },
Profile: { screen: Profile },
TodoDetailChecked: { screen: TodoDetailChecked },
TodoPage: { screen: TodoPage }
});
export default Router;

This problem about parent child problem.
Let's quotes from documentation:
It's important to note that this only happens if the screen is
rendered as a route by React Navigation (for example, in response to
this.props.navigation.navigate). For example, if we render
DetailsScreen as a child of HomeScreen, then DetailsScreen won't be
provided with the navigation prop, and when you press the
"Go to Details... again" button on the Home screen, the app will throw one of
the quintessential JavaScript exceptions "undefined is not an object".
To fix your problem is pass this.props.navigation to child component from higher component.
Let's do example:
App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import MyView from './MyView';
import { StackNavigator } from 'react-navigation';
import DetailsScreen from './DetailsScreen';
class App extends React.Component {
render() {
return (
<View style={styles.container}>
<MyView navigation={this.props.navigation} />
<Text>Open up App.js to start working on your app!</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default StackNavigator({
Home: {
screen: App,
},
Details: {
screen: DetailsScreen,
}
});
MyView.js
import React from 'react';
import { StyleSheet, Text, ListView } from 'react-native';
import TodoDetail from './TodoDetail';
export default class MyView extends React.Component {
constructor() {
super();
const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
this.state = {
dataSource: ds.cloneWithRows(['todo 1', 'todo 2']),
};
}
renderRow(todos) {
return <TodoDetail todos={todos} navigation={this.props.navigation} />;
}
render() {
return (
<ListView
enableEmptySections
dataSource={this.state.dataSource}
renderRow={(rowData) => this.renderRow(rowData)}
/>
);
}
}
TodoDetail.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
export default class TodoDetail extends React.Component {
componentDidMount() {
// console.log(this.props.navigation.navigate('Details'));
}
render() {
return (
<View>
<Text>Todo detail</Text>
<Text>{this.props.todos}</Text>
<Button
title="Go to Details"
onPress={() => this.props.navigation.navigate('Details', { itemDetail: this.props.todos })}
/>
</View>
);
}
}
DetailsScreen.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default class DetailsScreen extends React.Component {
componentDidMount() {
console.log(this.props.navigation);
}
render() {
const { params } = this.props.navigation.state;
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Text>{ params.itemDetail }</Text>
</View>
);
}
}
so in here, you need to pass navigation={this.props.navigation} every child render. If you see MyView component pass navigation props <MyView navigation={this.props.navigation} />.
And inside of it <TodoDetail todos={todos} navigation={this.props.navigation} />, last TodoDetail will available this.props.navigation to access this.props.navigation.navigate.

Related

React Native: How to dispatch redux action from Custom Drawer

I have to dispatch logoutUser() action from CustomDrawerContentComponent. How can I do that?
I have a StackNavigator as well as Drawer Navigator in my app.
Also there is a CustomDrawerComponent to show the username of authenticated user as well as a sign up button in Drawer. Since it is outside the class, I'm unable to dispatch using props.
MainComponent.js
...other import statements
import {
fetchDishes,
fetchComments,
fetchPromos,
fetchLeaders,
logoutUser,
} from "../redux/ActionCreators";
const mapDispatchToProps = (dispatch) => ({
fetchDishes: () => dispatch(fetchDishes()),
fetchComments: () => dispatch(fetchComments()),
fetchPromos: () => dispatch(fetchPromos()),
fetchLeaders: () => dispatch(fetchLeaders()),
logoutUser: () => dispatch(logoutUser()),
});
const handleSignOut = () => {
//Here I have to dispatch logoutUser() but props.logoutUser() says undefined.
};
const CustomDrawerContentComponent = (props) => (
<ScrollView>
<SafeAreaView
style={styles.container}
forceInset={{ top: "always", horizontal: "never" }}
>
<View style={styles.drawerHeader}>
<View style={{ flex: 1 }}>
<Image
source={require("./images/newlogo.png")}
style={styles.drawerImage}
/>
</View>
<View style={{ flex: 2 }}>
<Text style={styles.drawerHeaderText}>Ristorante Con Fusion</Text>
</View>
</View>
<View style={styles.displayName}>
<Avatar
title={props.screenProps.name.match(/\b(\w)/g).join("")}
rounded
>
{" "}
</Avatar>
<Text style={{ fontSize: 22, marginLeft: 5, color: "#fff" }}>
Hello, {props.screenProps.name}
</Text>
</View>
<DrawerItems {...props} />
<TouchableOpacity onPress={() => handleSignOut()}> //Here I am calling the function
<View style={{ flexDirection: "row", justifyContent: "center" }}>
<Icon name="sign-out" type="font-awesome" size={24} color="blue" />
<Text>Sign Out</Text>
</View>
</TouchableOpacity>
</SafeAreaView>
</ScrollView>
);
const MainNavigator = createDrawerNavigator(
{
Home: {
screen: HomeNavigator,
navigationOptions: {
title: "Home",
drawerLabel: "Home",
drawerIcon: ({ tintColor, focused }) => (
<Icon name="home" type="font-awesome" size={24} color={tintColor} />
),
},
},
...
...
...
{
initialRouteName: "Home",
drawerBackgroundColor: "#D1C4E9",
contentComponent: CustomDrawerContentComponent,
}
);
class Main extends Component {
componentDidMount() {
this.props.fetchDishes();
this.props.fetchComments();
this.props.fetchPromos();
this.props.fetchLeaders();
};
render() {
var displayName = this.props.user.user.displayName;
if (displayName == undefined) displayName = this.props.user.name;
return (
<Fragment>
<View
style={{
flex: 1,
paddingTop:
Platform.OS === "ios" ? 0 : Expo.Constants.statusBarHeight,
}}
>
<MainNavigator screenProps={{ name: displayName }} />
</View>
</Fragment>
);
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Main);
You can use the following to import useDispatch
import { useDispatch } from 'react-redux'
and then call it in your handleSignOut like so:
const handleSignOut = () => {
const dispatch = useDispatch()
dispatch(logoutUser())
//Continue with normal logout and maybe other dispatches...
};
Your component is not connected to redux. You are not using mapDispatchToProps anywhere else besides declaring it. Please use connect() method https://react-redux.js.org/api/connect

Trying to get Navigation to work between pages in Native react

How do I connect my page2.js and page3.js to my CounterApp.js page, so far i only got my page2 and page3 connected with a button, and i can go back and fore between these 2 pages, but i need a button for my CounterApp.js page
CounterApp.js ///////////////////////////////////////////////////////////////////////////////////
import {Image} from 'react-native';
import React, { Component } from "react";
import {
View,
Text,
StyleSheet,
TouchableOpacity
} from "react-native";
import { connect } from 'react-redux'
class CounterApp extends Component {
render() {
return (
<View style={styles.container}>
<View style={{ flexDirection: 'row', width: 200, justifyContent: 'space-around' }}>
<TouchableOpacity onPress={() => this.props.increaseCounter()}>
<Text style={{ fontSize: 20 }}>Increase</Text>
</TouchableOpacity>
<Text style={{ fontSize: 20 }}>{this.props.counter}</Text>
<TouchableOpacity onPress={() => this.props.decreaseCounter()}>
<Text style={{ fontSize: 20 }}>Decrease</Text>
</TouchableOpacity>
</View>
<Image source={{uri: 'https://facebook.github.io/react/logo-og.png'}}
style={{width: 200, height: 200}} />
<View style={{ flexDirection: 'row', width: 200, justifyContent: 'space-around' }}>
<TouchableOpacity onPress={() => this.props.increaseCounter2()}>
<Text style={{ fontSize: 20 }}>Increase</Text>
</TouchableOpacity>
<Text style={{ fontSize: 20 }}>{this.props.counter2}</Text>
<TouchableOpacity onPress={() => this.props.decreaseCounter2()}>
<Text style={{ fontSize: 20 }}>Decrease</Text>
</TouchableOpacity>
</View>
<Image source={{uri: 'https://facebook.github.io/react/logo-og.png'}}
style={{width: 200, height: 200}} />
</View>
);
}
}
function mapStateToProps(state) {
return {
counter: state.counter,
counter2: state.counter2,
}
}
function mapDispatchToProps(dispatch) {
return {
increaseCounter: () => dispatch({ type: 'INCREASE_COUNTER' }),
decreaseCounter: () => dispatch({ type: 'DECREASE_COUNTER' }),
increaseCounter2: () => dispatch({ type: 'INCREASE_COUNTER2' }),
decreaseCounter2: () => dispatch({ type: 'DECREASE_COUNTER2' }),
}
}
export default connect(mapStateToProps, mapDispatchToProps )(CounterApp)
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}
});
page2.js /////////////////////////////////////////////////////////////////////
import React, {Component} from 'react';
import {Button} from 'react-native';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
const {navigate} = this.props.navigation;
return (
<>
<Button
title="Go to Jane's profile"
onPress={() => this.props.navigation.navigate('Profile', {name: 'Jane'})}
/>
</>
);
}
}
export default HomeScreen;
page3.js ///////////////////////////////////////////////////////////////////////////////////////
import React, {Component} from 'react';
import {Button} from 'react-native';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
const {navigate} = this.props.navigation;
return (
<>
<Button
title="Go to Jane's home"
onPress={() => this.props.navigation.navigate('Home', {name: 'Jane'})}
/></>
);
}
}
export default HomeScreen;
mainnav.js ////////////////////////////////////////////////////////////////////////////////////////
import HomeScreen from './page2'
import ProfileScreen from './page3'
import CounterScreen from './CounterApp'
import {createStackNavigator} from 'react-navigation-stack';
const MainNavigator = createStackNavigator({
Home: {screen: HomeScreen},
Profile: {screen: ProfileScreen},
counter: {screen: CounterScreen}
},{initialRouteName:"Home"});
export default MainNavigator;

How to get params in other App Container - React Navigation?

I want to use the params I passed to Profile Screen and he is in a separate App Container,
And I create TopTabs and put it in a specific AppContainer because I don't have any way to use it in a one AppContainer so how I Get these Params from another AppContainer?
So My Code here's
First thing, now I'm in the Map Screen and want to navigate to profile screen and pass some params like this
this.props.navigation.navigate('ProviderProfile', {
providerId: marker.id,
providerName: marker.name,
providerService: marker.service,
gKey: marker.gKey,
token: marker.token._55,
region: region
}
And here is Profile Screen, Contain let's say Card and TobTabs "I wrap it in a separate AppContainer"
and want to use params I passed in these TopTabs "every single tab" so how to handle these OR pass these params to every single Tab?
ProviderProfile.js
import React, { Component } from "react";
import Icon from "react-native-vector-icons/Ionicons";
import firebase from "react-native-firebase";
import { createAppContainer } from "react-navigation";
import { NavTabs } from "./ProviderTabs/NabTabs";
import { View, Text, StyleSheet, TouchableOpacity, Image } from "react-native";
console.disableYellowBox = true;
class ProviderProfile extends Component {
static navigationOptions = ({ navigation }) => {
const { state } = navigation;
return {
title: ` ${state.params.providerName}` || "profile"
};
};
constructor(props) {
super(props);
this.state = {
providerId: this.props.navigation.getParam("providerId"),
providerService: this.props.navigation.getParam("providerService"),
providerName: this.props.navigation.getParam("providerName"),
gKey: this.props.navigation.getParam("gKey"),
token: this.props.navigation.getParam("token"),
region: this.props.navigation.getParam("region"),
fav: false
};
}
_addToFavorite = () => {
const { providerName, providerService, providerId, fav } = this.state;
const currentUser = firebase.auth().currentUser.uid;
this.setState({ fav: !fav });
const ref = firebase
.database()
.ref(`favorites/${currentUser}/${providerId}`);
if (!fav) {
ref
.set({
ProviderId: providerId,
providerName: providerName,
providerService: providerService
})
.then(() => alert("Great, Added to your favorite list"));
} else {
ref.remove();
}
};
render() {
const {
providerName,
providerService,
providerId,
fav,
gKey,
region,
token
} = this.state;
return (
<View style={styles.container}>
{/* <Text>{gKey}</Text> */}
<Image
resizeMode="contain"
source={require("../assets/marker.png")}
/>
<View>
<View>
<Icon
name={`ios-heart${fav ? "" : "-empty"}`}
size={35}
color="#f00"
onPress={this._addToFavorite}
/>
</View>
<Text>
<Icon name="ios-star" size={20} color="#f2ba13" />
<Icon name="ios-star" size={20} color="#f2ba13" />
<Icon name="ios-star" size={20} color="#f2ba13" />
<Icon name="ios-star-half" size={20} color="#f2ba13" />
<Icon name="ios-star-outline" size={20} color="#f2ba13" />
</Text>
<Text style={{ fontSize: 19, color: "#000", padding: 5 }}>
{providerName}
</Text>
<Text>
Service: <Text>{providerService}</Text>
</Text>
<View style={{ flexDirection: "row", marginTop: 10 }}>
<TouchableOpacity
onPress={() => alert("Message")}
>
<Text>
Message
</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() =>
this.props.navigation.navigate("Order", {
providerName,
providerId,
providerService,
gKey,
token,
region
})
}
>
<Text
>
Send Order
</Text>
</TouchableOpacity>
</View>
</View>
<Roots /> // Here's Tabs
</View>
);
}
}
const Roots = createAppContainer(NavTabs);
export default ProviderProfile;
And Here is a Tabs Screen "NavTabs"
import {
createMaterialTopTabNavigator,
} from "react-navigation";
import AboutScreen from "./About";
import GalaryScreen from "./Galary";
import ReviewsScreen from "./Reviews";
export const NavTabs = createMaterialTopTabNavigator(
{
About: { screen: AboutScreen },
Galaty: { screen: GalaryScreen },
Reviews: { screen: ReviewsScreen }
},
{
tabBarOptions: {
activeTintColor: "#fff",
inactiveTintColor: "#ddd",
tabStyle: {
justifyContent: "center"
},
indicatorStyle: {
backgroundColor: "#fcc11e"
},
style: {
backgroundColor: "#347ed8"
}
}
}
);
As you see, I want to use the username in Tab "About"
or other Tabs
Send params:
this.props.navigation.navigate('RouteName', { /* params go here */ })
Get params:
this.props.navigation.getParam(paramName, defaultValue)
Example:
this.props.navigation.navigate('NameListScreen', { names:["John","Mary"] })
let params = this.props.navigation.getParam(names, [])
I haven't use React Navigation myself but in their documentation say you can pass props to App Containers, so as you have defined the state with the props from the MapScreen you should probably pass them as props where you have defined your NavTabs Component as <Roots />
Also, there is another alternative to want to achieve as they present in here and it will be done in a redux way.

Invariant Violation: Element type is invalid:expected a string(for built-in components) or a class/function(for composite component)but got: undefined

I am using following version to build a app
React-Native:0.57.1
react-native-cli:2.0.1
node:v8.11.3
npm:5.6.0
It says that check render method of List. So i am sharing the code of List.js below.
List.js
import React, {Component} from 'react';
import {
Text,
TextInput,
Dimensions,
ImageBackground,
Alert,
TouchableHighlight,
StyleSheet,
NativeModules,
PixelRatio,
ToastAndroid,
View,
ListView,
RefreshControl,
BackHandler
} from 'react-native';
import RNExitApp from 'react-native-exit-app';
import Icon from 'react-native-vector-icons/MaterialIcons';
import Icon1 from 'react-native-vector-icons/Foundation';
import IconHeart from 'react-native-vector-icons/FontAwesome';
import Realm from 'realm';
import { Toolbar, ThemeProvider} from 'react-native-material-ui';
import { NavigationActions,Header,StackNavigator } from 'react-navigation';
import Auth from './lib/Categories/Auth';
import AndroidBackButton from './back-button';
import LocalStorage from './lib/Categories/LocalStorage';
import {MetaData,SchemaData,HistoryTable} from './Schema';
import { sync } from './Components/Sync'
import strings from './Language';
import Storage from './lib/Categories/Storage';
import costyle from './Styling';
import { GoogleAnalyticsTracker } from "react-native-google-analytics-bridge";
let tracker = new GoogleAnalyticsTracker(strings.analytics);
var RNFS=require('react-native-fs');
const SCREEN_WIDTH = Dimensions.get('window').width;
const SCREEN_HEIGHT = Dimensions.get('window').height;
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
const uiTheme = {
palette: {
primaryColor: '#008975',
},
toolbar:{
container:{height:SCREEN_HEIGHT*0.08}
},
};
export default class List extends Component
{
constructor(props) {
super(props);
this.state = {
dataSource: ds.cloneWithRows([]),
realm:null,
refresh:false,
timePassed:false,
c:0,
data:[],
}
}
componentWillMount(){
Realm.open({
schema:[SchemaData,MetaData]
}).then(realm => {
this.setState({realm});
})
.done(()=>this.loadJSONData())
tracker.trackEvent("Home Screen", "opened");
}
componentWillUnmount(){
tracker.trackEvent("Home Screen","closed");
}
setSearchText(searchText){
var arr=this.state.data;
let results = [];
for(var i = 0; i < arr.length; i++)
{
if(arr[i].property1.toLowerCase().includes(searchText.toLowerCase()))
results.push(arr[i]);
else if(arr[i].doctor.toLowerCase().includes(searchText.toLowerCase()))
results.push(arr[i]);
}
this.setState({
searchText,
dataSource: this.state.dataSource.cloneWithRows(results),
});
}
backOfList(){
setTimeout(() => {this.setState({timePassed:true,c:0})}, 5000);
var c=this.state.c;
if (!this.state.timePassed)
{
this.setState({c:c+1});
if(this.state.c==1)
ToastAndroid.show(strings.pressExit, ToastAndroid.SHORT);
else if(this.state.c==2){
RNExitApp.exitApp();
}
}
else
{
this.setState({c:1});
ToastAndroid.show(strings.pressExit, ToastAndroid.SHORT);
this.setState({timePassed:false});
}
console.log(c);
}
async sync() {
this.setState({ refresh: true });
setTimeout(() => {this.setState({ refresh: false });}, 10000);
try{
await sync()
}catch(e){
if(e.name=='TypeError'){
await Auth.init();
}
else
ToastAndroid.show(strings.wrongWarning, ToastAndroid.SHORT);
}
this.loadJSONData()
}
loadJSONData()
{
var arr=[];
this.setState({dataSource: this.state.dataSource.cloneWithRows(arr)})
console.log("inside loadJSONData")
arr=this.state.realm.objects('SchemaData').sorted('modifiedTime',true);
arr=arr.filtered('userId==$0 AND active==$1',LocalStorage.getItem('UserId'),true);
this.setState({ refresh: false });
this.setState({ data:arr,dataSource: this.state.dataSource.cloneWithRows(arr)})
}
renderedRow(data){
const { navigate } = this.props.navigation;
var files=[],file=[];
var pCount;
var lCount;
var oCount;
console.log('Render row:',data)
if(this.state.realm!=null)
{
file=this.state.realm.objects('MetaData');
files=file.filtered('ailmentId == $0 AND category == "Prescription" AND active == $1',data.id,true)
pCount=files.length;
files=file.filtered('ailmentId == $0 AND category == "LabWork" AND active == $1',data.id,true)
lCount=files.length;
files=file.filtered('ailmentId == $0 AND category == "Others" AND active == $1',data.id,true)
oCount=files.length;
}
return(
<View>
<View style={{flex:1,marginTop:10,flexDirection:'row'}}>
<View style={{flex:10}}>
<TouchableHighlight underlayColor='transparent' onPress={()=>{navigate('imageGrid',{loadData:this.loadJSONData.bind(this),type:'Details',data:data})}}>
<View>
<Text style={{marginLeft:15,fontSize:20,fontWeight:'bold'}}>
{data.property1}
</Text>
<Text style={{marginLeft:15,fontSize:15}}>{strings.prescription}: <Text style={{fontWeight:'bold'}}>{pCount}</Text> <Text style={{color:'#babcbc'}}>|</Text>{strings.labworkHeading2}: <Text style={{fontWeight:'bold'}}>{lCount}</Text> <Text style={{color:'#babcbc'}}>|</Text> {strings.others}: <Text style={{fontWeight:'bold'}}>{oCount}</Text></Text>
</View>
</TouchableHighlight>
</View>
<View style={styles.icons}>
<Icon1 name='page-add' size={SCREEN_WIDTH*0.1} onPress={()=>{navigate('PickCategory',{data:data})}}/>
</View>
</View>
<View style={[costyle.line,{marginLeft:10}]}/>
</View>
);
}
render(){
const { navigate } = this.props.navigation;
return (
<View style={costyle.bagContainer}>
<AndroidBackButton onPress={()=>{this.backOfList();return true}} />
<ThemeProvider uiTheme={uiTheme}>
<Toolbar
leftElement="menu"
size={SCREEN_WIDTH * 0.0675}
centerElement={strings.AddDetails}
searchable={{
autoFocus: true,
placeholder: strings.placeholderSearch,
onChangeText:this.setSearchText.bind(this)
}}
style={{
titleText:{fontFamily:'sans-serif',fontSize:20,fontWeight:'normal'}
}}
onLeftElementPress= {()=> navigate('DrawerOpen')}
/>
</ThemeProvider>
<ImageBackground
source={require('./Images/BackgroundImage.png')}
style={{ width: SCREEN_WIDTH,height: SCREEN_WIDTH * 0.1}}>
<Text style={{marginTop:5,color:'#005b4a',fontSize:22,marginLeft:20,fontWeight:'bold'}}>{strings.wellnessrecord}</Text>
</ImageBackground>
<Text></Text>
<ListView enableEmptySections
dataSource={this.state.dataSource}
renderRow={this.renderedRow.bind(this)}
refreshControl={ <RefreshControl refreshing={this.state.refresh} onRefresh={this.sync.bind(this)} /> }/>
<View>
<TouchableHighlight style={styles.addButton}
underlayColor='#4b9e77' onPress={()=>{navigate('AddDetails',{goback:'true'})}}>
<Icon name='add' size={32} color='white'/>
</TouchableHighlight>
</View>
</View>
);
}
static navigationOptions= ({ navigation }) => ({
header:null,
});
}
const styles = StyleSheet.create({
icons: {
flex:1,
alignItems:'flex-end',
justifyContent:'center',
paddingRight:20,
paddingBottom:10,
},
addButton: {
backgroundColor: '#005b4a',
height: 60,
width: 60,
borderRadius: 30,
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
bottom: 20,
right:20,
}
});
I am getting this error and unable to resolve it, although this error has been discussed in stackoverflow but i have tried those code but still it didn't worked. Kindly help.

Is there a way to access the function of screen component of DrawerNavigator into menu button of DrawerNavigator in react native?

I have a Drawer Navigator which have screens.
Now I want to access the one screen function in menu button of drawer.
Let suppose
Drawer Navigator:
const Drawer = createDrawerNavigator(
{
Main: {
path: "/Main",
screen: MainScreen
},
LikeScreen: {
path: "/Like",
screen: LikeScreen
},
DislikeScreen: {
path: "/Dislike",
screen: DislikeScreen
}
},
{
initialRouteName: "Main",
drawerWidth: widthPercentageToDP("60%"),
contentComponent: SideMenu,
headerMode: "screen"
}
);
MainScreen:
export default class MainScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
TurnMeOnMainFilterModal: false
};
}
_OpenFilterModel=()=> this.setState({ TurnMeOnMainFilterModal: true });
_closeFilterModel=()=> this.setState({ TurnMeOnMainFilterModal: false });
render() {
return <View>
<Modal
animationType="slide"
transparent={true}
visible={this.state.TurnMeOnMainFilterModal}
presentationStyle="overFullScreen"
>
<View style={Style1.ModalViewContainer}>
<View style={Style1.ModalView}>
<TouchableWithoutFeedback onPress={this._closeFilterModel}>
<View style={Style1.ModalCloseButton}>
<Icon
color="#7BB141"
name="check"
size={widthPercentageToDP("8%")}
/>
</View>
</TouchableWithoutFeedback>
</View>
</View>
</Modal>
</View>
}
SideMenu:
import { NavigationActions } from "react-navigation";
class SideMenu extends Component {
constructor(props) {
super(props);
this.state = { selected: 1, Language:props.screenProps.Language };
this.changer = this.changer.bind(this);
}
navigateToScreen = (route, num) => () => {
const navigateAction = NavigationActions.navigate({ routeName: route });
this.changer(num);
this.props.navigation.dispatch(navigateAction);
};
changer(Num) {
this.setState({ selected: Num });
}
render() {
const { Language } = this.state;
const color1 = "#0DA4D0",
color2 = "grey";
return (
<View style={Style.Parentcontainer}>
<TouchableWithoutFeedback onPress={this.navigateToScreen("Main", 1)}>
<View style={Style.ChildUpperContainer}>
<Icon
name="home-outline"
size={widthPercentageToDP("7%")}
color={this.state.selected === 1 ? color1 : color2}
/>
<Text
style={[
Style.textFont,
this.state.selected === 1
? { color: color1 }
: { color: color2 }
]}
>
Home
</Text>
</View>
</TouchableWithoutFeedback>
{this.state.selected === 1 && (
<TouchableWithoutFeedback
onPress={() => {
////////////////////(Here I want The Function Of Screen to be access)/////////////////////////
this.props.navigation.closeDrawer();
}}
>
<View style={Style.ChildUpperContainer}>
<Icon
name="filter-outline"
size={widthPercentageToDP("7%")}
color={color2}
/>
<Text style={[Style.textFont, { color: color2 }]}>
Home Filter
</Text>
</View>
</TouchableWithoutFeedback>
)}
<TouchableWithoutFeedback
onPress={this.navigateToScreen("LikeScreen", 3)}
>
<View style={Style.ChildUpperContainer}>
<Icon
name="thumb-up-outline"
size={widthPercentageToDP("7%")}
color={this.state.selected === 3 ? color1 : color2}
/>
<Text
style={[
Style.textFont,
this.state.selected === 3
? { color: color1 }
: { color: color2 }
]}
>
Liked
</Text>
</View>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback
onPress={this.navigateToScreen("DislikeScreen", 4)}
>
<View style={Style.ChildUpperContainer}>
<Icon
name="thumb-down-outline"
size={widthPercentageToDP("7%")}
color={this.state.selected === 4 ? color1 : color2}
/>
<Text
style={[
Style.textFont,
this.state.selected === 4
? { color: color1 }
: { color: color2 }
]}
>
Disliked
</Text>
</View>
</TouchableWithoutFeedback>
</View>
);
}
}
SideMenu.propTypes = {
navigation: PropTypes.object
};
export default SideMenu;
In the sidemenu ,I commented where I want to access MainScreen's Function _OpenFilterModel to be performed.
Actually I want to open the Modal of screen (which will perform more operation on current screen Component) through clicking on menu of Drawer in which screen Component itself is a child.
I end up with my own following solution:
In MainScreen:
componentWillMount() {
this.props.navigation.setParams({
FilterModel: this._OpenFilterModel
});
}
In SideMenu:
onPress={() => {
////HERE TO CAll
this.props.navigation.state.routes[0].params.FilterModel();
this.props.navigation.closeDrawer();
}}
or
onPress={() => {
////HERE TO CAll
this.props.items[0].params.FilterModel();
this.props.navigation.closeDrawer();
}}
routes[0] and items[0] is accordingly to createDrawerNavigator Screen Sequence . Main Screen Is at index 0.

Categories

Resources