【问题标题】:React Native navigation with onPress function in for loop在 for 循环中使用 onPress 函数反应本机导航
【发布时间】:2017-11-20 05:47:49
【问题描述】:

我正在尝试在 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>
            );
      }
}

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

【问题讨论】:

    标签: react-native


    【解决方案1】:

    这是因为当 onPress() 被调用时,它会获取变量“i”的值。由于您正在使用该变量进行循环,因此它将一直到最后一个值。所以当 onPress 被调用时,它会使用那个值(因为它没有将 'i' 的每个值绑定到每个 onPress())。

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

    类似这样的:

    你的 ImageComponent。将 source、imageString 和 onPress 函数作为 props 传递给它。

    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

    【讨论】:

    • 感谢您的帮助。我试图运行你的代码,但我的 ImageView 现在完全是空的。我试图找出错误,但除了删除 中的逗号之外,我找不到问题所在
    • 我只复制粘贴了您的代码并分离出图像组件。我没有运行我在答案中编写的代码。这只是一个关于如何实现应该打开正确图像的画廊的想法。您的代码的问题在于它始终采用最后一个值“i”。但是我编写代码的方式应该可以解决这个问题。您可以使用将 imageurl 和回调传递给 GalleryImage 组件的想法,而不是使用此代码。您还可以输入日志语句并检查您是否在 GallerImage 组件中获得了正确的道具?
    • 此外,如果图像不可见,则样式可能存在问题。
    猜你喜欢
    • 2020-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-14
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    相关资源
    最近更新 更多