简体   繁体   中英

Access data from a function [React Native]

I am trying to get the original size image from a url and display the image based on its ratio. I used Image.getSize() to do the job.

This is what I've done so far :

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>
  )
}

See the Image.getSize() , I can get the width and height of the image but I am unable to access the data from outside. Means I cannot get the width and height set in <FastImage /> style as the data cannot be accessed.

How should I pass it through there? For some reason, I am unable to use setState() cause I'm using a function from a different separated file.

The problem you are having is, that Image.getSize is an async function, that will finish, after you have return your content. Since imgWidth and imgHeight are just normal variables, that will not trigger a rerender on change.

The way to go here would either be to put imgWidth and imgHeight into the state of this function.

With a class component you can just use this.setState({ imgHeight: ..., imgWidht: ...}); . With a functional component, you would need to use the stateHook .

Here is an example for a class component.

    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}
                </>
            );
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM