2017-06-17 46 views
0

我正在尝试在React Native中制作一个图像库。在For循环中使用onPress函数反应本机导航

什么我现在有一个网站,看起来像这样: imageView

的图像是只有9所需要的数组像这样的测试图片:

var imagesLoaded = 
[ 
     require('./image_1.jpg'), 
     require('./image_2.jpg'), 
     require('./image_3.jpg'), 
     require('./image_4.jpg'), 
     require('./image_5.jpg'), 
     require('./image_6.jpg'), 
     require('./image_7.jpg'), 
     require('./image_8.jpg'), 
     require('./image_9.jpg') 
]; 

我现在想要能够做的就是点击一张图片,这个图片会导致一个新的页面在黑色背景上单独点击图片。

这是画廊代码:

class ImageView extends Component 
{ 
     static navigationOptions = 
     { 
      title: 'ImageView', 
     }; 

     render() 
     { 
      const { navigate } = this.props.navigation; 

      var images = []; 

      for (var i = 0; i < 200; i++) 
      { 
        var imageString = 'Image #' + (i+1); 

        images.push(
         <TouchableHighlight key={i} onPress={() => navigate('ImageTap', {imageSrc: imagesLoaded[i%9]})}> 
           <View style={styles.imageContainer}> 
            <Image source={imagesLoaded[i%9]} style={styles.images}/> 
            <Text style={styles.imageText}>{imageString}</Text> 
           </View> 
         </TouchableHighlight> 
       ) 
      } 

      return (
        <ScrollView> 
         <View style={{flex: 1, flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'center'}}> 
           {images} 
         </View> 
        </ScrollView> 
      ); 
     } 
} 

这是新的一页这是应该打开代码:

class ImageTap extends Component 
{ 
     static navigationOptions = 
     { 
      title: 'ImageView', 
     }; 

     render() 
     { 
      const { params } = this.props.navigation.state; 

      return (
        <View style={{backgroundColor: 'black', flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center'}}> 
         <Image source={params.imageSrc} style={{flex: 1}}/> 
        </View> 
      ); 
     } 
} 

但是,什么情况是,总是最后一个图像的封闭环打开。无论哪个图像被点击。如果我将迭代器i作为参数提供给新页面并记录下来,我总是得到199.我做错了什么?

回答

1

这是因为当onPress()被调用时,它接受变量'i'的值。由于您正在循环使用该变量,因此它将一直持续到最后一个值。所以当onPress被调用时,它将使用该值(因为它没有将'i'的每个值绑定到每个onPress())。

更好的解决方案是,您可以将另一个组件中的图像组件提取出来,并将它传递给图像源并在那里处理onPress。

事情是这样的:

ImageComponent。将它的源码,imageString和onPress函数作为道具传递。

const GalleryImage = ({ source, imageString, onPress }) => { 
    return (
     <TouchableHighlight onPress={onPress(src)}> 
      <View style={styles.imageContainer}> 
       <Image source={source} style={styles.images}/> 
       <Text style={styles.imageText}>{imageString}</Text> 
      </View> 
     </TouchableHighlight> 
    ); 
}; 

const styles = { 
    imageContainer: { 
    .... 
    }, 
    images: { 
    .... 
    }, 
    imageTex: { 
    .... 
    } 
} 

export default GalleryImage; 

ImageView的组件

import GalleryImage from './GallerImage'; 

class ImageView extends Component { 

    constructor(props) { 
     super(props); 
     this.handleNavigation = this.handleNavigation.bind(this); 
    } 

    static navigationOptions = { 
     title: 'ImageView', 
    }; 

    handleNavigation(source) { 
     this.props.navigation.navigate('ImageTap', {imageSrc: source}); 
    } 

    renderGalleryImages() { 
     return imagesLoaded.map(
      (src, i) => { 
       <GalleryImage 
        key={i}, 
        source={src}, 
        imageString = {'Image #' + (i+1)}, 
        onPress= {this.handleNavigation} 
       /> 
      } 
     ); 
    } 

    render() { 
     return (
       <ScrollView> 
        <View style={{flex: 1, flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'center'}}> 
          {this.renderGalleryImages()} 
        </View> 
       </ScrollView> 
     ); 
    } 
} 

另外,最好不要使用索引键元素可能影响性能,如果项目在列表中移动:https://facebook.github.io/react/docs/reconciliation.html#recursing-on-children

+0

感谢您的帮助。 我试图运行你的代码,但我的ImageView现在完全是空的。我试图找到这个错误,但除了在中删除逗号之外,我找不到错在哪里 –

+0

我复制了粘贴的代码,并分离出了图像组件。我没有运行我在答案中写的代码。这只是一个关于如何实现应该打开正确图像的图库的想法。你的代码的问题只是它总是取最后一个值'i'。但是我编写代码的方式应该解决这个问题。您可以使用将图像和回调传递给GalleryImage组件的想法,而不是使用此代码。你也可以把日志报告,并检查你是否得到正确的道具在你的GallerImage组件或不? –

+0

此外,如果图像不可见,那么造型可能会有一些问题。 –