Reputation: 29
I have been reading a lot of answers on SO as well as GitHub issues trying to implement a solution, but have been unable to come up with a solution for this situation.
Here is a representation of my code:
class MeetingsScreen extends React.Component {
constructor(props) {
super(props)
this.state = {
upcomingMeeting: [],
refreshing: false
};
}
async handlePress() {
const user = await AsyncStorage.getItem('User');
this.props.navigation.navigate('WriteSummary', { id: user.id, type: 'submit' });
}
printUpcomingMeetings = () => {
return (<View style={styles.meeting}>
<Button
containerStyle={styles.meetingButton}
style={styles.meetingButtonText}
onPress={() => this.handlePress(user.id)}
Press me to write summary!
</Button>
</View>);
}
}
render () {
return (<View style={{flex:1}} key={this.state.refreshing}>
{ this.printUpcomingMeetings() }
</View>);
}
}
class WriteSummaryScreen extends React.Component {
constructor(props) {
super(props)
this.state = {
storageId: '',
normalId: -1,
type: '',
curSummary: ''
}
}
componentDidMount = () => {
const { params } = this.props.navigation.state;
const { id, type } = params ? params : null;
const storageId = 'summary_' + id;
this.setState({storageId:storageId});
this.setState({normalId:id});
this.setState({type:type});
AsyncStorage.getItem(storageId).then((value) => this.setSkipValue(value));
}
async setSkipValue (value) {
if (value !== null) {
this.setState({ 'curSummary': value });
} else {
this.setState({ 'curSummary': '' });
}
}
async saveSummary (text) {
this.setState({'curSummary': text});
await AsyncStorage.setItem(this.state.storageId, text);
}
async handleSubmit() {
const user = await AsyncStorage.getItem('User');
if (this.state.type === 'submit') {
// post insert
const postres = fetch (url + '/create-summary', {
method: 'POST',
body: JSON.stringify({
AppointmentId: this.state.normalId,
SummaryText: this.state.curSummary,
UserId: user.Id
}),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}
})
.catch((error) => {
console.error(error);
});
} else {
// post update
const postres = fetch (url + '/update-summary', {
method: 'POST',
body: JSON.stringify({
AppointmentId: this.state.normalId,
SummaryText: this.state.curSummary,
UserId: user.Id
}),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}
})
.catch((error) => {
console.error(error);
});
}
this.props.navigation.navigate('Meetings');
}
render () {
return <View style={{flex:1}}>
<View>
<View style={{height:25, backgroundColor: colors.vikingBlue}}></View>
<View style={{height:30, backgroundColor: colors.white}}></View>
<View style={{flexDirection:'row', backgroundColor: colors.white, alignItems:'center'}}>
<View style={{width:5}}></View>
<TouchableOpacity onPress={() => this.props.navigation.goBack()} activeOpacity={0.5}>
<Image style={{width:30, height:30}} source={require('./assets/icons8-back-50.png')} />
</TouchableOpacity>
<View style={{width:10}}></View>
<View style={{width:mainTitleWidth,textAlign:'center',alignItems:'center'}}>
<Text style={{fontSize:22}}>Settings</Text>
</View>
<TouchableOpacity onPress={() => this.props.navigation.navigate('HelpModal')} activeOpacity={0.5}>
<Image style={{width:30, height:30}} source={require('./assets/help.png')} />
</TouchableOpacity>
</View>
<View style={{height:30, backgroundColor: colors.white}}></View>
</View>
<TextInput
multiline
numberOfLines={6}
style={styles.summaryInput}
onChangeText={text => saveSummary(text)}
value={this.state.curSummary} />
<Button
containerStyle={styles.summaryButton}
style={styles.summaryButtonText}
onPress={this.handleSubmit()}>
Submit
</Button>
</View>
}
}
function HomeStack() {
return (
<Tab.Navigator
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Meetings" component={MeetingsScreen} />
<Tab.Screen name="Topics" component={TopicsScreen} />
</Tab.Navigator>
);
}
export default class AppContainer extends React.Component {
// Main rendering function. Always begins on the SplashScreen, which checks user login status and directs to Meetings. I left it out and the other Tab navigator screens for less clutter.
render() {
return (
<NavigationContainer>
<Stack.Navigator headerMode='none' initialRouteName='Splash'>
<Stack.Screen name='Splash' component={SplashScreen} />
<Stack.Screen name='Main' component={HomeStack} />
<Stack.Screen name='WriteSummary' component={WriteSummaryScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
};
I get the error TypeError: undefined is not an object (evaluating '_this7.props.navigation.state.params)'
after pressing the button on MeetingsScreen and navigating to WriteSummaryScreen.
What confuses me is the screen is navigated to, so the data should have been passed. What am I missing?
Upvotes: 0
Views: 59
Reputation: 10675
You can access parametes like below if its class based component:
class WriteSummaryScreen extends React.Component {
const {id, type} = this.props.route.params;
//........
for the functional component:
const WriteSummaryScreen =({navigation, route})=>{
const {id, type} = route.params;
//..........
}
Upvotes: 1
Reputation: 29
What ended up working for me was the following:
const id = this.props.route.params.id;
const type = this.props.route.params.type;
Upvotes: 0
Reputation: 1405
You can access the params that you have passed from a screen using the getParam
function.
so you can use this code:
const id = this.props.navigation.getParam("id");
const type = this.props.navigation.getParam("type");
Upvotes: 0