在for循环中使用onPress函数实现本机导航

时间:2017-06-17 15:39:08

标签: react-native

我正在尝试在React Native中创建一个图片库。

我目前拥有的网站如下所示: 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>
            );
      }
}

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

1 个答案:

答案 0 :(得分:2)

这是因为当调用onPress()时,它接受变量'i'的值。由于您使用该变量进行循环,因此它将一直运行到最后一个值。因此,当调用onPress时,它将使用该值(因为它不会将'i'的每个值绑定到每个onPress())。

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

这样的事情:

您的 ImageComponent 。将source,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>
        );
    }
}

此外,最好不要将index用作元素的键,因为如果项目在列表中移动,可能会影响性能:https://facebook.github.io/react/docs/reconciliation.html#recursing-on-children