首页 > 解决方案 > 从函数访问数据 [React Native]

问题描述

我正在尝试从 url 获取原始大小的图像并根据其比例显示图像。我曾经Image.getSize()做过这项工作。

这是我到目前为止所做的:

function displayimgThumb(file_url){
  var win         = Dimensions.get('window');
  var ratio       = 0
  var imgWidth    = 0;
  var imgHeight   = 0;

  Image.getSize(file_url, (width, height) => {
    ratio     = win.width / width;
    imgWidth  = win.width;
    imgHeight = height * ratio;
  });

  return (
    <TouchableOpacity>
      <FastImage
        style={{
          width: imgWidth,
          height: imgHeight
        }}
        source={{
            uri: file_url,
            priority: FastImage.priority.normal,
        }}
        resizeMode={FastImage.resizeMode.contain} />
    </TouchableOpacity>
  )
}

请参阅Image.getSize(),我可以获取图像的宽度和高度,但无法从外部访问数据。意味着我无法获取<FastImage />样式中设置的宽度和高度,因为无法访问数据。

我应该如何通过那里?出于某种原因,我无法使用,setState()因为我正在使用来自不同分隔文件的函数。

标签: javascriptfunctionreact-nativereturn-value

解决方案


您遇到的问题是, Image.getSize 是一个异步函数,它将在您返回内容后完成。由于imgWidthimgHeight只是普通变量,因此不会触发更改时的重新渲染。

去这里的方法要么是放入这个函数的状态imgWidthimgHeight

使用类组件,您可以只使用this.setState({ imgHeight: ..., imgWidht: ...});. 使用功能组件,您需要使用stateHook.

这是一个类组件的示例。

    import React from 'react';
    ...

    class MyComponent extends React.Component {
        constructor (props) {
            super(props);

            this.state = {
                imgWidth: null,
                imgHeight: null,
                ratio: null,
            };
        }

        function displayimgThumb (file_url) {
            // here you are getting the image dimensions from state again.
            const { imgWidth, imgHeight, ratio } = this.state;
            var win       = Dimensions.get('window');

            // just checking, we actually have dimensions (image is loaded, to prevent wrong rendering)
            // only call "Image.getSize" when we don't have a size yet - if you go this way it is more performant, but you might to have to add a special case for screen size changes
            if (imgWidth === null) { 
               Image.getSize(file_url, (width, height) => {
                   ratio     = win.width / width;

                   // here you set the state as soon as you have the image size and thereby trigger a rerender of the whole component, but this time with image dimensions you know
                   this.setState({
                       imgWidth: win.width,
                       imgHeight: (height * ratio),
                       ratio,
                   });
               });

               return (
                  <View>
                     // JUST SHOW SOMETHING UNTIL THE IMAGE SIZE HAS LOADED (which usually doesn't take very long)
                     // or return null here, to show nothing until that happens
                  </View>
               );
            }

            return (
                <TouchableOpacity>
                    <FastImage
                        style={{
                            width: imgWidth,
                            height: imgHeight
                        }}
                        source={{
                            uri: file_url,
                            priority: FastImage.priority.normal,
                        }}
                        resizeMode={FastImage.resizeMode.contain}
                    />
                </TouchableOpacity>
            )
        }

        function render() {
            return (
                <>
                    {this.displayimgThumb}
                </>
            );
        }
    }

推荐阅读