从“ Home.js”访问“ MyShows.js”屏幕后,一旦返回“ Home.js”并按一个键,事件监听器将开始运行两次。已经看了几个小时,并测试了一切的感觉。在有人创建“ Home.js”组件之后,我添加了“ MyShows.js”组件。可以很好地访问任何其他屏幕,例如“指南”。您可以在我的代码中看到问题所在吗?使用React导航将它们连接起来,将省略Redux代码。让我知道您是否需要更多信息。
Home.js
import React, { Component } from 'react';
import { ActivityIndicator, AppState, BackHandler, DeviceEventEmitter, Image, StyleSheet, Text, View } from 'react-native';
// Components
import TopBar from '../Common/TopBarContainer';
import CardList from './CardList';
import HomeMenu from './Containers/HomeMenuContainer';
// Mock Data
import { mockCards } from '../../assets/mock';
export default class Home extends Component {
constructor() {
super();
this.state = {
isCardsShowing: false,
cards: mockCards,
menu: [
{
menuTitle: 'MY SHOWS',
menuCallback: () => this.props.currentPage === 'Home' && this.navigate('MyShows')
},
{
menuTitle: 'WHAT TO WATCH',
menuCallback: () => this.props.currentPage === 'Home' && console.log('What to watch')
},
{
menuTitle: 'GUIDE',
menuCallback: () => this.props.currentPage === 'Home' && this.navigate('Guide')
},
{
menuTitle: 'SEARCH',
menuCallback: () => this.props.currentPage === 'Home' && this.navigate('Search')
},
{
menuTitle: 'SETTINGS',
menuCallback: () => this.props.currentPage === 'Home' && this.navigate('Menu')
}
]
}
}
shouldComponentUpdate(nextProps) {
return nextProps.currentPage === 'Home';
}
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', () => true);
if (!this._homeEventEmitter) {
this._homeEventEmitter = DeviceEventEmitter.addListener('onKeyDown', this._listenerFunction);
}
setTimeout(() => {
this.setState({ isCardsShowing: true });
if (!this._homeEventEmitter) {
this._homeEventEmitter = DeviceEventEmitter.addListener('onKeyDown', this._listenerFunction);
}
}, 3500);
// Become inactive/active scroll view issue -- START
// var backgroundStartTime;
AppState.addEventListener('change', (nextAppState) => {
if (nextAppState === 'background') {
// backgroundStartTime = new Date();
this.setState({ isCardsShowing: false });
} else {
setTimeout(() => {
this.setState({ isCardsShowing: true });
if (!this._homeEventEmitter) {
this._homeEventEmitter = DeviceEventEmitter.addListener('onKeyDown', this._listenerFunction);
}
}, 3500);
}
}); // Become inactive/active scroll view issue -- END
}
componentWillReceiveProps(nextProps) {
if (this.props.currentPage !== 'Home' && nextProps.currentPage === 'Home') {
// Solves scroll view issue -- START
this.setState({ isCardsShowing: false });
setTimeout(() => {
this.setState({ isCardsShowing: true });
if (!this._homeEventEmitter) {
this._homeEventEmitter = DeviceEventEmitter.addListener('onKeyDown', this._listenerFunction);
}
}, 3500);
setTimeout(() => this.refs.cardList && this.refs.cardList.refs.cardList.scrollToIndex({ index: nextProps.selectedCard, viewOffset: 100 }), 3550);
// Solves scroll view issue -- END
}
}
_listenerFunction = (keyEvent) => {
const { selectedCard, isMenuEnabled, onToggleMenu, onChangeCard } = this.props;
if (this.props.currentPage === 'Home') {
if (keyEvent.keyCode === 19) { // Up
onToggleMenu(true);
}
if (keyEvent.keyCode === 20) { // Down
onToggleMenu(false);
}
if (keyEvent.keyCode === 21) { // Left
if (!isMenuEnabled) {
this.state.cards.unshift(this.state.cards[this.state.cards.length - 1]);
this.state.cards.pop();
this.forceUpdate();
}
}
if (keyEvent.keyCode === 22) { // Right
if (!isMenuEnabled) {
this.state.cards.push(this.state.cards[0]);
this.state.cards.shift();
this.forceUpdate();
}
}
if (keyEvent.keyCode === 23 || keyEvent.keyCode === 66) { //Select (OK)
if (!isMenuEnabled) {
this._homeEventEmitter.remove();
this._homeEventEmitter = null;
this.props.navigation.navigate('ShowInfo', { cardInfo: this.state.cards[selectedCard] });
}
}
}
}
componentWillUnmount() {
this._homeEventEmitter && this._homeEventEmitter.remove();
this._homeEventEmitter = null;
}
navigate = (page) => {
if(page === 'Menu') {
this.props.onStopLiveTV();
}
this.props.onChangePage(page);
this.props.navigation.navigate(page);
}
render() {
const { currentTime, height, width, navigation } = this.props.screenProps;
const { cards, menu } = this.state;
const { routeName } = this.props.navigation.state;
const { currentPage, selectedCard, isMenuEnabled, isPlayerShowing } = this.props;
return (
routeName === 'Home' ?
<View style={styles.mainContainer}>
<View style={{ position: 'absolute', height, width }}>
<Image source={{ uri: cards[selectedCard].image }} resizeMode='cover' style={{ flex: 1 }} />
</View>
<TopBar
currentTime={currentTime}
topBarText='HOME'
pushInTime={isPlayerShowing} />
<View style={{ flex: 11.5, paddingVertical: 20, backgroundColor: 'rgba(0, 0, 0, 0.75)' }}>
<View style={{ flex: 1, justifyContent: 'flex-end' }}>
<HomeMenu menuItems={menu} isEnabled={isMenuEnabled} currentPage={currentPage} />
</View>
<View style={{ flex: 1, justifyContent: 'center' }}>
{
this.state.isCardsShowing ?
<CardList
ref='cardList'
cards={cards}
selectedCard={selectedCard}
isEnabled={!isMenuEnabled}
showHeaderText={true} /> :
<ActivityIndicator size={50} color='#D3D3D3' />
}
</View>
</View>
<View style={styles.footer}>
<Text style={{ color: '#CBBB56', fontSize: 18 }}>A</Text>
<Text style={styles.footerText}>options</Text>
</View>
</View> : null
);
}
}
HomeMenu.js
import React, { Component } from 'react';
import { BackHandler, DeviceEventEmitter, StyleSheet, FlatList, ScrollView, Image, Text, View } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
// import * as Animatable from 'react-native-animatable';
export default class HomeMenu extends Component {
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', () => true);
if (!this._homeMenuEmitter) {
this._homeMenuEmitter = DeviceEventEmitter.addListener('onKeyDown', this._listenerFunction);
}
}
_listenerFunction = (keyEvent) => {
const { menuIndex, isEnabled, menuItems, changeMenuIndex, currentPage } = this.props;
if (isEnabled && currentPage === 'Home'){
if (keyEvent.keyCode === 21) { // Left
if (menuIndex > 0) {
changeMenuIndex(menuIndex - 1);
// this.refs.cardList.refs.cardList.scrollToIndex({ index: this.state.selectedCard - 1, viewOffset: 100});
}
}
if (keyEvent.keyCode === 22) { // Right
if (menuIndex < 4) {
changeMenuIndex(menuIndex + 1);
// this.refs.cardList.refs.cardList.scrollToIndex({ index: this.state.selectedCard - 1, viewOffset: 100});
}
}
if (keyEvent.keyCode === 23 || keyEvent.keyCode === 66) { //Select (OK)
if (menuItems[menuIndex].menuCallback) {
menuItems[menuIndex].menuCallback();
}
}
}
}
render() {
const { menuIndex, menuItems, isEnabled } = this.props;
return (
<View style={styles.menuContainer}>
{
menuItems.map((menuItem, i) => (
<View key={i} style={[styles.menuItemContainer]}>
{
menuItem.menuTitle === 'SETTINGS' ?
<Icon key={i} name="cog" size={30} color={menuIndex === i && isEnabled ? '#eaeaea' : '#909090'}/> :
<Text style={menuIndex === i && isEnabled ? styles.selectedMenuText : styles.menuText}>{menuItem.menuTitle}</Text>
}
</View>
))
}
</View>
);
}
}
MyShows.js
import React, { Component } from 'react';
import { ActivityIndicator, DeviceEventEmitter, BackHandler, StyleSheet,FlatList, Image, Text, View } from 'react-native';
import TopBar from '../Common/TopBarContainer';
import { mockCards } from '../../assets/mock';
import MyShowsCardList from './MyShowsCardList';
export default class MyShows extends Component {
constructor() {
super()
}
_keyExtractor = (item, index) => index.toString();
_renderItem = ({ item, index }) => (
this.props.titlesIndex === index && this.props.cardsEnabled === false ?
<View style={[styles.selectedTextContainer, {width: this.props.screenProps.width}]}>
<View style={styles.textContainer}>
<Text style={{ fontFamily: 'OpenSans-Regular', color: 'black', fontSize: 22, marginLeft: 10 }}>
{item.program_name}
</Text>
</View>
</View>
:
<Text style={{ marginLeft: 80, color: '#EAEAEA', fontFamily: 'OpenSans-Light', fontSize: 22 }}>
{item.program_name}
</Text>
);
shouldComponentUpdate(nextProps) {
return nextProps.currentPage === 'MyShows';
}
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', () => true);
if(!this._myShowsEventEmitter)
this._myShowsEventEmitter = DeviceEventEmitter.addListener('onKeyDown', this._listenerFunction);
this.props.onUpdateCards(mockCards);
this.props.onGetAssets(614);
}
_listenerFunction = (keyEvent) => {
if (this.props.currentPage === 'MyShows') {
if (keyEvent.keyCode === 19) { // Up
console.log("UP");
if(this.props.titlesIndex === 0 && this.props.cardsEnabled === false){
this.props.onCardMenuToggle(!this.props.cardsEnabled);
}else if(this.props.cardsEnabled === false){
this.props.onChangeTitlesIndex(this.props.titlesIndex - 1);
}else{
console.log("Card menu already activated")
}
}
if (keyEvent.keyCode === 20) { // Down
console.log("DOWN");
if(this.props.cardsEnabled){
//Collapsing animation goes here
this.props.onCardMenuToggle(!this.props.cardsEnabled);
}else if(this.props.assetData.length > (this.props.titlesIndex + 1)){
this.props.onChangeTitlesIndex(this.props.titlesIndex + 1);
}else{
console.log("Max titles reached");
}
}
if (keyEvent.keyCode === 21) { // Left
if(this.props.cardsEnabled){
console.log("LEFT");
this.props.onMoveLeft(this.props.cardData);
console.log(this.props.cardData);
// this.forceUpdate();
}
}
if (keyEvent.keyCode === 22) { // Right
if(this.props.cardsEnabled){
console.log("RIGHT");
this.props.onMoveRight(this.props.cardData);
console.log(this.props.cardData);
}
}
// UPDATE BASED ON CARD OR TITLE SELECTED
if (keyEvent.keyCode === 23 || keyEvent.keyCode === 66) { //Select (OK)
this._myShowsEventEmitter.remove();
this._myShowsEventEmitter = null;
this.props.onChangePage('SelectedRecording');
this.props.navigation.navigate('SelectedRecording');
}
if (keyEvent.keyCode === 4 || keyEvent.keyCode === 111) { //Back
this._myShowsEventEmitter.remove();
this._myShowsEventEmitter = null;
this.props.onChangePage('Home');
this.props.navigation.navigate('Home');
}
}
}
componentWillUnmount() {
this._myShowsEventEmitter && this._myShowsEventEmitter.remove();
}
render() {
const { currentTime, height, width, navigation } = this.props.screenProps;
const prependedCards = [{name: 'View: RECORDINGS', id: 0 }, ...this.props.cardData];
return (
<View style={styles.mainContainer}>
<View style={{ position: 'absolute', height, width }}>
{/* Placeholder Image */}
<Image source={{ uri: this.props.cardData[0].image }} resizeMode='cover' style={{ flex: 1 }} />
</View>
<TopBar
currentTime={currentTime}
topBarText='MY SHOWS'
pushInTime={false} //Change to isPlayerShowing prop
dvrMemory={true}
/>
<View style={{ flex: 11.5, paddingVertical: 20, backgroundColor: 'rgba(0, 0, 0, 0.75)' }}>
<View style={{ flex: 1, justifyContent: 'center' }}>
{/* UPDATE isCardsShowing */}
{/* { this.props.subscriberData.data !== undefined &&
this.props.subscriberData.data.length > 0 && */}
{/* } */}
{/* Placeholder items and id */}
{this.props.loading ?
<ActivityIndicator size={50} color='#D3D3D3' />
:
<View style={{ flex: 1, justifyContent: 'center' }}>
<MyShowsCardList
style={{ flex: 1 , paddingTop: 30 }}
// ref='cardList'
cards={this.props.cardData}
showHeaderText={false}
isEnabled={this.props.cardsEnabled}
/>
<FlatList
style={{ flex: 2 }}
contentContainerStyle={{ paddingTop: 20 }}
data={this.props.assetData}
renderItem={this._renderItem}
keyExtractor={this._keyExtractor}
extraData={this.props}
/>
</View>
}
</View>
</View>
<View style={styles.footer}>
<Text style={{ color: '#CBBB56', fontSize: 18, paddingLeft: 50 }}>A</Text>
<Text style={styles.footerText}>options</Text>
<Text style={{ color: '#397F8A', fontSize: 18, paddingLeft: 50 }}>B</Text>
<Text style={styles.footerText}>list sorted by name</Text>
<Text style={{ color: '#993F4E', fontSize: 18, paddingLeft: 50 }}>C</Text>
<Text style={styles.footerText}>recordings</Text>
</View>
</View>
)
};
}