【问题标题】:React Native CameraRoll.getPhotos API doesn't render the resultsReact Native CameraRoll.getPhotos API 不呈现结果
【发布时间】:2016-09-07 18:17:32
【问题描述】:

您好,我有以下课程,我正在尝试从相机胶卷中获取照片并显示它。

class CameraRollProject extends Component {
  constructor(props) {
    super(props);
    this.state = {
     images: []
    };
  }

  componentWillMount() {
    const fetchParams = {
      first: 25,
    };
    CameraRoll.getPhotos(fetchParams, this.storeImages, this.logImageError);
  }

  storeImages(data) {
    const assets = data.edges;
    const images = assets.map((asset) => asset.node.image);
    this.state.images =  images;
  }

  logImageError(err) {
    console.log(err);
  }

  render() {
      return (
        <ScrollView style={styles.container}>
          <View style={styles.imageGrid}>
            { this.state.images.map((image) => <Image style={styles.image} source={{ uri: image.uri }} />) }
          </View>          
        </ScrollView>
      );
  }
};

export default CameraRollProject;

问题是我的渲染函数在我的 CameraRoll.getPhotos 承诺得到解决之前被调用。所以我没有得到任何照片。

为了解决这个问题,我把我的程序改成了下面的

render() {
      return CameraRoll.getPhotos(fetchParams, this.storeImages, this.logImageError)
        .then(() => {
          return (
            <ScrollView style={styles.container}>
              <View style={styles.imageGrid}>
                { this.state.images.map((image) => <Image style={styles.image} source={{ uri: image.uri }} />) }
              </View>          
            </ScrollView>
          );
        });
  }

但是这给了我以下错误

在上述情况下我该怎么办?如何确保渲染仅在 CameraRoll.getPhotos 得到解决后才有效。

【问题讨论】:

    标签: javascript reactjs react-native es6-promise react-native-component


    【解决方案1】:

    所以我解决了这个问题。我的问题的主要原因是我没有正确使用 CameraRoll.getPhotos 作为 Promise。我在函数内部传递了不正确的参数。为了解决这个问题,我摆脱了以下功能

     storeImages(data) {
        const assets = data.edges;
        const images = assets.map((asset) => asset.node.image);
        this.state.images =  images;
      }
    
      logImageError(err) {
        console.log(err);
      }
    

    让我的 CameraRoll.getPhotos 如下所示

    CameraRoll.getPhotos({first: 5}).then(
      (data) =>{
        const assets = data.edges
        const images = assets.map((asset) => asset.node.image);
            this.setState({
              isCameraLoaded: true,
              images: images
            })
      },
      (error) => {
         console.warn(error);
      }
    );
    

    这是我在 react-native 中从 CameraRoll 获取图片的完整代码,以防万一有人感兴趣

    class CameraRollProject extends Component {
      constructor(props) {
        super(props);
        this.state = {
         images: [],
         isCameraLoaded: false
        };
      }
    
      componentWillMount() {
        CameraRoll.getPhotos({first: 5}).then(
          (data) =>{
            const assets = data.edges;
            const images = assets.map((asset) => asset.node.image);
            this.setState({
              isCameraLoaded: true,
              images: images
            })
          },
          (error) => {
            console.warn(error);
          }
        );
      }
    
      render() {
          if (!this.state.isCameraLoaded) {
            return (
              <View>
                <Text>Loading ...</Text>
              </View>
              );
          }
          return (
            <ScrollView style={styles.container}>
              <View style={styles.imageGrid}>
                { this.state.images.map((image) => <Image style={styles.image} source={{ uri: image.uri }} />) }
              </View>          
            </ScrollView>
          );
      }
    };
    
    export default CameraRollProject;
    

    【讨论】:

      【解决方案2】:

      我认为你应该使用react-native-image-picker

      你有很多参数可以随心所欲地检索图片

        selectPhotoTapped() {
          const options = {
            title: 'Choose a picture',
            cancelButtonTitle: 'Back',
            takePhotoButtonTitle: 'Take a picture...',
            chooseFromLibraryButtonTitle: 'Choose from my pictures..',
            quality: 1,
            maxWidth: 300,
            maxHeight: 300,
            allowsEditing: true,
            mediaType: 'photo',
            storageOptions: {
              skipBackup: true
            }
          }
      

      它比CameraRollProject 更容易处理,并且文档解释得很好。因为你会做它非常适合。 (适用于 iOS 和 Android)

      【讨论】:

      • 我想使用原生的CameraRoll.getPhotos而不是任何第三方库。
      【解决方案3】:

      一种方法是使用ListView 而不是Scrollview,因为您可以使用datasource。以下是您如何执行此操作的示例:

      constructor(props) {
        super(props);
      
        const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
        this.state = { dataSource: ds.cloneWithRows([]) };
      
        this.loadPhotos();
      }
      
      loadPhotos() {
        const fetchParams = {
          first: 25,
        };
      
        CameraRoll.getPhotos(fetchParams).then((data) => {
          this.state.dataSource.cloneWithRows(data.edges);
        }).catch((e) => {
          console.log(e);
        });
      }
      

      这样,您会呈现一个空列表(以及良好 UX 的加载状态),然后在获取完成后将数据设置在 ListView 中。

      如果您想坚持使用ScrollView 和映射图像,您还需要某种加载状态,直到照片加载。希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 2018-11-04
        • 1970-01-01
        • 2020-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-11
        • 1970-01-01
        • 2017-04-23
        相关资源
        最近更新 更多