[英]Navigate to another screen from Flat list item
I'm trying to navigate to another screen when I click on one of the items on the flat list. 单击平面列表中的一个项目时,我试图导航到另一个屏幕。
The code that I have here worked for a couple of days but now it doesn't, straight away when the app loads, the EventDetailScreen is opened even before I click on any of the flat list items, then when I press the back button from the EventDetailScreen which brings me back to the EventListScreen, if I click on any of the list items nothing happens and I don't get brought to the EventDetailScreen. 我在这里工作的代码已经使用了几天,但是现在没有了,当应用程序加载时,即使在我单击任何平面列表项目之前,EventDetailScreen也已打开,然后当我按EventDetailScreen,这使我回到EventListScreen,如果我单击任何列表项,则什么也不会发生,也不会进入EventDetailScreen。
I also get an error: 我也得到一个错误:
Warning: Cannot update during an existing state transition (such as within
render
or another component's constructor). 警告:在现有状态转换期间(例如在render
或其他组件的构造函数中)无法更新。 Render methods should be a pure function of props and state; 渲染方法应该纯粹是道具和状态的函数; constructor side-effects are an anti-pattern, but can be moved tocomponentWillMount
. 构造函数的副作用是反模式,但是可以将其移至componentWillMount
。
I am new to React Native so any help would be much appreciated! 我是React Native的新手,所以我们将不胜感激!
I am using: "react-navigation": "^2.7.0",
"react": "16.4.1", "react-native": "0.56.0",
我正在使用: "react-navigation": "^2.7.0",
"react": "16.4.1", "react-native": "0.56.0",
I used this answer Navigating to each item in FlatList on SO to get it working initially. 我使用此答案导航至 SO上FlatList的每个项目,以使其最初开始工作。
EventListScreen.js EventListScreen.js
export default class EventListScreen extends Component {
constructor() {
super();
this.ref = firebase.firestore();
this.unsubsribe = null;
this.state = {
eventName: '',
eventLocation: '',
loading: true,
events: [],
};
}
componentDidMount() {
console.log('EventsListScreen1');
this.unsubsribe = this.ref.onSnapshot(this.onCollectionUpdate)
}
componentWillUnmount() {
this.unsubsribe();
}
openDetails = () => {
this.props.navigation.navigate('EventDetailScreen');
};
render() {
if (this.state.loading) {
return null;
}
return (
<Container>
<FlatList
data={this.state.events}
// Get the item data by referencing as a new function to it
renderItem={({item}) =>
<Event
openDetails={() => this.openDetails()}
{...item} />}
/>
<View style={{flex: 1}}>
<Fab
active={this.state.active}
direction="left"
containerStyle={{}}
style={{backgroundColor: '#5067FF'}}
position="bottomRight"
onPress={() =>
this.props.navigation.navigate('EventForm')
}>
<Icon
name="ios-add"/>
</Fab>
</View>
</Container>
);
}
Event.js Event.js
export default class Event extends Component {
render() {
return (
<Card>
<CardSection>
<Text>{this.props.eventName}</Text>
</CardSection>
<TouchableOpacity
onPress={this.props.openDetails()}
>
<CardSection>
<Image
style={{
width: 350,
height: 300
}}
source={{
uri: this.props.imageDownloadUrl
}}
/>
</CardSection>
<CardSection>
<Text>{this.props.eventLocation}</Text>
</CardSection>
</TouchableOpacity>
</Card>
);
}};
EventDetailScreen.js EventDetailScreen.js
export default class EventDetailScreen extends Component {
render() {
/* 2. Get the param, provide a fallback value if not available */
const { navigation } = this.props;
const itemId = navigation.getParam('itemId', 'NO-ID');
return (
<View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}}>
<Text>Details Screen</Text>
</View>
);
}}
This is probably because of the following line in Event
component. 这可能是因为Event
组件中的以下行。
<TouchableOpacity
onPress={this.props.openDetails()} // <-- this line to be specific
> ... </>
As soon as EventScreenList
renders the list, the first row executes openDetails()
method which switches the screen. EventScreenList
呈现列表后,第一行将执行openDetails()
方法,该方法将切换屏幕。
You can avoid this by using onPress={() => this.props.openDetails()}
. 您可以使用onPress={() => this.props.openDetails()}
来避免这种情况。
Also its a good idea to have the following in constructor or componentDidMount of EventScreenList component because both the function uses this
context of the statement. 在EventScreenList组件的构造函数或componentDidMount中具有以下内容也是一个好主意,因为这两个函数都使用this
语句的上下文。
this.openDetails = this.openDetails.bind(this);
this.onCollectionUpdate = this.onCollectionUpdate.bind(this);
To check the significance of above statement, try 要检查上述陈述的重要性,请尝试
<TouchableOpacity
onPress={this.props.openDetails} // <-- this line
> ... </>
The warning message is due to navigation before state update finishes. 该警告消息是由于状态更新完成之前的导航而引起的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.