navigation.getParam is not a function - react-native

I have a problem when getting value. It always returns me an error navigation.getParam is not a function.
Account.js
<TouchableOpacity onPress={() => this.props.navigation.navigate('Detail_Account',
{id:'hello'})}>
<Block style={ styles.content }></Block>
</TouchableOpacity>
in my Detail Account
const { navigation } = this.props;
const id = navigation.getParam('id', 'empty')
return(
<Block>
<Text>
{id}
</Text>
</Block>
);
Suggest any solution for this.

1) Go to your package.json file in your project.
2) Change the version of #react-navigation/stack to a 5.x.x.
Example:
"#react-navigation/stack": "^5.2.14",
3) Run npm install.
4) Edit your DetailAccount.js as follows.
import React from 'react';
import { StyleSheet, View, Alert } from 'react-native';
import { Block, Text } from 'galio-framework';
class DetailAccount extends React.Component {
constructor(props) {
super(props);
}
render() {
const id = this.props.route.params.id;
return (
<Block>
<Text>{id}</Text>
</Block>
);
}
}
export default DetailAccount;
5) Run npm start and restart your project.
You will fix the problem.

Try this solution
Account.js
<TouchableOpacity
onPress={() =>
this.props.navigation.navigate("Detail_Account", { id: "hello" })
}
>
<Block style={styles.content}></Block>
</TouchableOpacity>;
Detail Account
const { id } = this.props.route.params;
return (
<Block>
<Text>{id}</Text>
</Block>
);

You can do like this...
const { navigation } = this.props;
const id = navigation.state.params.id;
return (
<Block>
<Text>{id}</Text>
</Block>
);
UPDATE
When configured the whole code of DetailAccount.js, the problem was, props are not received in to the particular component. So, the components doesn't know what this.props is.
Please update your DetailAccount.js as follows.
import React from 'react';
import { StyleSheet, View, Alert } from 'react-native';
import { Block, Text } from 'galio-framework';
class DetailAccount extends React.Component {
constructor(props) {
super(props);
}
render() {
const id = this.props.navigation.state.params.id;
return (
<Block>
<Text>{id}</Text>
</Block>
);
}
}
export default DetailAccount;
That means, simply you have to add the below part to your DetailAccount commponent.
constructor(props) {
super(props);
}

Related

React Native: Updating the state from child to parent and then pass updated props at second component

I am trying to change the value of props at second Recipe-Component updating the state.
I tried to use timer, alerts. but I had also problem.
App js:
import React, { Component } from "react";
import Recipe from "./Recipe";
import {Text, View } from "react-native";
export default class App extends Component {
constructor() {
super();
this.state = {
name: "Pancaces",
isYummy: true
};
}
update = (s) => {
this.setState({name : s.name, isYummy: s.isYummy });
}
render() {
return (
<View style={{alignItems: 'center'}}>
<Recipe update={this.update} name={this.state.name} isYummy={this.state.isYummy} delay={false}/>
<Text>{this.state.name}</Text>
<Recipe name={this.state.name} isYummy={this.state.isYummy} delay={true}/>
</View>
);
}
}
Recipe.js
import React, * as react from "react";
import PropTypes from "prop-types";
import { Text, View } from "react-native";
import styles from "./styles.js";
export default class Recipe extends react.Component{
static propTypes = {
name: PropTypes.string.isRequired,
isYummy: PropTypes.bool.isRequired
};
constructor(props){
super(props)
this.state = {
update : this.update,
name : this.props.name,
isYummy: this.props.isYummy
}
if(this.props.update) this.props.update(({name:'Lentils', isYummy:false}))
};
render() {
return (
<View style={styles.container}>
<Text style={styles.text_container} >{this.state.name}</Text>
{this.state.isYummy ? <Text>THIS RECIPE IS YUMMY</Text> : null}
</View>
);
}
}
Current Output is:
Pancakes
THIS RECIPE IS YUMMY
Lentils
Pancakes
THIS RECIPE IS YUMMY
I expect output
Pancakes
THIS RECIPE IS YUMMY
Lentils
Lentils
SOLVED
I believe this is happening because you are trying to display the values from your state instead of your props and since the constructor isn't called a second time after updating, your state doesn't get reassigned. Here's what I would do:
//Recipe.js
constructor (props)
{
super(props);
if (this.props.update)
this.props.update(({name:'Lentils', isYummy:false}));
}
render()
{
return (
<View style={styles.container}>
<Text style={styles.text_container}>
{this.props.name}
</Text>
{this.props.isYummy &&
<Text>
THIS RECIPE IS YUMMY
</Text>
}
</View>
);
}

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?.();
}

Undefined is not an object for react navigation

I have two components for my project, and I have gone through all the steps for react navigation as follow:
// App.js
import React from 'react';
import Main from './app/componenets/Main'
import details from './app/componenets/details'
import { createStackNavigator, createAppContainer } from 'react-navigation'
const mainNavigator = createStackNavigator(
{
MainScreen: Main,
detailsScreen: details,
},
{
initialRouteName :'MainScreen'
}
);
const AppContainer = createAppContainer(mainNavigator);
export default class App extends React.Component{
render() {
return(
<AppContainer />
);
}
}
Then I have my Main.js which I have a method as follow:
import React from 'react';
import {
StyleSheet ,
Text,
View,
} from 'react-native'
import Note from './Note'
import detail from './details'
import { createStackNavigator, createAppContainer } from "react-navigation";
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}>
<View style={styles.footer}>
<TextInput
onChangeText={(noteText) => this.setState({noteText})}
style={styles.textInput}
placeholder='What is your next Task?'
placeholderTextColor='white'
underlineColorAndroid = 'transparent'
>
</TextInput>
</View>
<TouchableOpacity onPress={this.addNote.bind(this)} style={styles.addButton}>
<Text style={styles.addButtonText}> + </Text>
</TouchableOpacity>
</View>
);
}
//This method is declared in my Note.js
goToNoteDetail=(key)=>{
this.props.navigation.navigate('detailsScreen')
}
}
//Styles which I didn't post to be short in code here
But when I try to do the navigation I get this error:
'undefined is not and object(evaluating 'this.props.val.date')
Do I need to pass the props in a way? or should I do anything else? I am new to React native and confused!
in order to access this.props make arrow function or bind the function in constructor.
goToDetail=()=>{
this.props.navigation.navigate('detailsScreen')
}
Just remove createAppContainer
const AppContainer = mainNavigator;
and tell me what react-navigation that you work with

change view in react native (0.5)

I have 2 views and I want to move from the first one to the second one without using createStackNavigator
There´s no need to use navigation because the first view is just a welcome screen
import React from 'react';
import { View, Text, Button } from 'react-native';
class HomeScreen extends React.Component {
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text>Welcome!</Text>
<Button
title="sign In"
onPress={() => navigate('SignInScreen')}
/>
</View>
);
}
}
class SignInScreen extends React.Component {
render() {
return (
<View>
<Text>Sign In screen</Text>
</View>
);
}
}
export default HomeScreen
the error I´m getting is
TypeError: undefined is not an object (evaluating 'this.props.navigation.navigate')
thank you.
Use a flag on state. When you click the button on HomeScreen, it will change the flag to true, which will allow the conditional statement to call the SignInScreen to be rendered.
import React from 'react';
import { View, Text, Button } from 'react-native';
class HomeScreen extends React.Component {
state = {
loggedIn: false,
};
render() {
const { navigate } = this.props.navigation;
return this.loggedIn ? (
<SignInScreen />
) : (
<View>
<Text>Welcome!</Text>
<Button
title="sign In"
onPress={() => this.setState({ loggedIn: true })}
/>
</View>
);
}
}
class SignInScreen extends React.Component {
render() {
return (
<View>
<Text>Sign In screen</Text>
</View>
);
}
}
export default HomeScreen;

How to setState without using .bind(this) in react-native?

I have no idea How to set state.
Below is my code...
import React from 'react';
import { StyleSheet, Text, View, TouchableHighlight, AsyncStorage, ListView } from 'react-native';
export default class App extends React.Component {
constructor(){
super();
this.state = {
myLeader: 'Joe',
};
}
setMyLeader(name){
this.setState({
myLeader: name
});
}
render() {
return (
<View>
<TouchableHighlight
style={{padding: 30}}
onPress={this.setState(myLeader: 'xxx')}
>
<Text>foo</Text>
</TouchableHighlight>
</View>
);
}
}
error message is this. 'Can't find variable: myLeader'
How to fix this problem?
Inside your onPress function you can:
a) directly set the state
onPress={() => this.setState({ myLeader: 'xxx' })}
b) call your setLeader function
onPress={() => this.setMyLeader('xxx')}