Description
Environment
[skip envinfo]
{
"name": "my-new-project",
"main": "node_modules/expo/AppEntry.js",
"private": true,
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"eject": "expo eject",
"test": "node ./node_modules/jest/bin/jest.js --watchAll"
},
"jest": {
"preset": "jest-expo"
},
"dependencies": {
"@expo/samples": "2.1.1",
"axios": "^0.18.0",
"expo": "^30.0.1",
"react": "16.3.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-30.0.0.tar.gz",
"react-native-htmlview": "^0.13.0",
"react-navigation": "^2.16.0",
"react-redux": "^5.0.7",
"redux": "^4.0.0",
"redux-thunk": "^2.3.0"
},
"devDependencies": {
"jest-expo": "30.0.0"
}
}
I'm using create-react-native-app package, so I'm unable to run the mandatory command, but my environment is described above.
Description
I'm trying to navigate to another screen (Artist) by clicking on an element in a FlatList. This FlatList contains Artist instances, as set in the _renderListItem method. So far I've tried three different approaches (two of them commented out at the moment), but none of them seem to work:
**Method 1: NavigationActions
Method 2: this.props.navigation.navigate
Method 3: Navigator.push**
I managed to pass the params to the other screen, but unfortunately the navigation itself doesn't seem to work; I'm getting the expected values in my logs, but nothing happens and the app stays at LinksScreen (doesn't change screens).
Reproducible Demo
LinksScreen.js
import React, { Component } from 'react';
import { PropTypes } from 'prop-types';
import Artist from './Artist';
import { createStackNavigator, withNavigation, NavigationActions } from 'react-navigation';
import {
ScrollView,
StyleSheet,
View,
Text,
Image,
FlatList,
ActivityIndicator,
TouchableOpacity,
TouchableHighlight,
} from 'react-native';
export default class LinksScreen extends React.Component {
constructor(props) {
super(props);
this._onAlertTypePressed = this._onAlertTypePressed.bind(this);
}
_onAlertTypePressed(typeId: string, typeName: string, imageUrl: string) {
console.log(typeId)
console.log(typeName)
console.log(imageUrl)
// NavigationActions
// NavigationActions.navigate({
// routeName: 'Artist',
// params: { itemId: typeId, itemName: typeName, itemImageUrl: imageUrl,},
// });
// NAVIGATE
this.props.navigation.navigate('HomeStack',{},
{
type: "Navigate",
routeName: "Artist",
params: {
itemId: typeId,
itemName: typeName,
itemImageUrl: imageUrl}
}
);
// PUSH
// this.props.navigator.push({
// screen: 'Artist',
// title: 'Artist',
// passProps: {
// itemId: typeId,
// itemName: typeName,
// itemImageUrl: imageUrl,
// },
// });
}
_renderListItem = ({item}) => (
<Artist
itemId={item.id}
itemName={item.title.rendered}
itemImageUrl={
item.better_featured_image
? item.better_featured_image.source_url
: 'http://54.168.73.151/wp-content/uploads/2018/04/brand-logo.jpg'
}
onPressItem={this._onAlertTypePressed}
/>
);
static navigationOptions = {
title: 'Links',
};
state = {
data: [],
isLoading: true,
isError: false,
};
// static propTypes = {
// navigation: PropTypes.shape({
// navigate: PropTypes.func.isRequired,
// }).isRequired,
// };
componentWillMount() {
fetch('http://54.168.73.151/wp-json/wp/v2/pages?parent=38&per_page=100')
.then(response => response.json())
.then(responseJson => {
responseJson.sort(
(a, b) => (a.title.rendered < b.title.rendered ? -1 : 1)
);
this.setState({
data: responseJson,
isLoading: false,
isError: false,
});
})
.catch(error => {
this.setState({
isLoading: false,
isError: true,
});
console.error(error);
});
}
// Not used anymore.
renderRow = item => (
<View style={styles.grid}>
<Image
style={styles.thumb}
source={{
uri: item.better_featured_image
? item.better_featured_image.source_url
: 'http://54.168.73.151/wp-content/uploads/2018/04/brand-logo.jpg',
}}
/>
<Text style={styles.title}>{item.title.rendered}</Text>
</View>
);
getKey = item => String(item.id);
renderComponent() {
if (this.state.isLoading) {
return <ActivityIndicator />;
} else if (this.state.isError) {
return <Text>Error loading data</Text>;
} else {
return (
<FlatList
numColumns={3}
contentContainerStyle={styles.elementsContainer}
data={this.state.data}
renderItem={this._renderListItem}
keyExtractor={this.getKey}
/>
);
}
}
render() {
return (
<View style={styles.container}>
<Text
style={{
fontSize: 20,
color: '#FFFFFF',
marginLeft: 4,
marginTop: 10,
}}>
RESIDENTS
</Text>
{this.renderComponent()}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#000000',
},
elementsContainer: {
backgroundColor: '#000000',
},
grid: {
marginTop: 15,
marginBottom: 15,
marginLeft: 5,
height: 125,
width: 115,
borderBottomWidth: 1,
borderBottomColor: '#191970',
},
title: {
color: '#FFFFFF',
textAlign: 'left',
fontSize: 12,
},
thumb: {
height: 110,
width: 110,
resizeMode: 'cover',
},
});
Artist.js
The console.log in the beginning of the _onPress() method seem to be working (the expected params have the correct values here), but I'm unable to navigate to this screen.
import React, { Component } from 'react';
import { createStackNavigator } from 'react-navigation';
import {
ScrollView,
StyleSheet,
View,
Text,
TouchableOpacity,
Image,
} from 'react-native';
class Artist extends React.PureComponent {
_onPress = () => {
// console.log(this.props)
const itemId = this.props.itemId
const itemName = this.props.itemName
const itemImageUrl = this.props.itemImageUrl
console.log(itemId)
console.log(itemName)
console.log(itemImageUrl)
// FOR PUSH
// this.props.onPressItem(
// this.props.itemid,
// this.props.itemName,
// this.props.itemImageUrl,
// );
// };
}
static navigationOptions = {
title: 'Artist',
};
render() {
return (
<TouchableOpacity
{...this.props}
style={styles.grid}
onPress={this._onPress}>
<Image
style={styles.image}
source={{uri: this.props.itemImageUrl}}
/>
<Text style={styles.title}>{this.props.itemName}</Text>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#000000',
},
grid: {
marginTop: 15,
marginBottom: 15,
marginLeft: 5,
height: 125,
width: 115,
borderBottomWidth: 1,
borderBottomColor: '#191970',
},
title: {
color: '#FFFFFF',
textAlign: 'left',
fontSize: 12,
},
image: {
height: 110,
width: 110,
resizeMode: 'cover',
},
});
export default Artist;
MainTabNavigator.js
Perhaps there is something wrong regarding the routing, so here is how it's done in my case.
import React from 'react';
import { Platform, AppRegistry } from 'react-native';
import { createStackNavigator, createBottomTabNavigator } from 'react-navigation';
import TabBarIcon from '../components/TabBarIcon';
import HomeScreen from '../screens/HomeScreen';
import LinksScreen from '../screens/LinksScreen';
import SettingsScreen from '../screens/SettingsScreen';
import Artist from '../screens/Artist';
const HomeStack = createStackNavigator({
Home: {
screen: HomeScreen,
},
Links: {
screen: LinksScreen,
},
Artist: {
screen: Artist,
},
});
AppRegistry.registerComponent('ParamsRepo', () => HomeStack);
export default HomeStack;