繁体   English   中英

基本反应本机问题隐蔽类到函数

[英]Basic react native question covert Class to Function

这可能听起来很傻,但我只是在这里学习我正在尝试将组件转换为基于函数的组件。 我做的一切都是正确的,但我被困在一些非常愚蠢的事情上

我有这个发现代码

export default class Discover extends React.PureComponent {
  state = {
    items: [],
  };
    cellRefs: {};

  constructor(props) {
    super(props);
    this.cellRefs = {};
  }

将 cellRefs 转换为使用我拥有的功能的正确方法是什么? 当我在我的类文件中执行此操作时,我尝试了所有方法,这很好,它为我提供了一个包含我需要的东西的对象。

const cell = this.cellRefs[item.key];

然而,

const cell = cellRefs[item.key];

只是给 undefined

转换后的组件的完整代码

import React, { useState, useEffect, useRef, Children } from 'react';
import {
  StyleSheet,
  Text,
  View,
  FlatList,
  Dimensions,
  TouchableOpacity,
  Image,
} from 'react-native';
import { Video } from 'expo-av';




const { height, width } = Dimensions.get('window');

const cellHeight = height * 0.6;
const cellWidth = width;

const viewabilityConfig = {
itemVisiblePercentThreshold: 80,
};



class Item extends React.PureComponent {
  video: any;
  componentWillUnmount() {
    if (this.video) {
      this.video.unloadAsync();
    }
  }

  async play() {
    const status = await this.video.getStatusAsync();
    if (status.isPlaying) {
      return;
    }
    return this.video.playAsync();
  }

  pause() {
    if (this.video) {
      this.video.pauseAsync();
    }
  }

  render() {
    const { id, poster, url } = this.props;
    const uri = url + '?bust=' + id;
    return (
      <View style={styles.cell}>
        <Image
          source={{
            uri: poster,
            cache: 'force-cache',
          }}
          style={[styles.full, styles.poster]}
        />
        <Video
          ref={ref => {
            this.video = ref;
          }}
          source={{ uri }}
          shouldPlay={false}
          isMuted
          isLooping
          resizeMode="cover"
          style={styles.full}
        />
        <View style={styles.overlay}>
          <Text style={styles.overlayText}>Item no. {id}</Text>
          <Text style={styles.overlayText}>Overlay text here</Text>
        </View>
      </View>
    );
  }
}







interface FeedListProps {

}

export const FeedList: React.FC<FeedListProps> = (props) => {
  const initialItems = [
    {
      id: 1,
      url: 'https://s3.eu-west-2.amazonaws.com/jensun-uploads/shout/IMG_1110.m4v',
      poster:
        'https://s3.eu-west-2.amazonaws.com/jensun-uploads/shout/norwaysailing.jpg',
    },
    {
      id: 2,
      url:
        'https://s3.eu-west-2.amazonaws.com/jensun-uploads/shout/croatia10s.mp4',
      poster:
        'https://s3.eu-west-2.amazonaws.com/jensun-uploads/shout/croatia10s.jpg',
    },
  ];
  const [items, setItems] = useState([]);
  //this.cellRefs = {};
  //let cellRefs: {};
  //cellRefs= {};
  const cellRefs = React.useRef({})
  const viewConfigRef = React.useRef({ itemVisiblePercentThreshold: 80 })
 

  useEffect(() => {
    loadItems();
    setTimeout(loadItems, 1000);
    setTimeout(loadItems, 1100);
    setTimeout(loadItems, 1200);
    setTimeout(loadItems, 1300);
  }, []);

  const _onViewableItemsChanged = React.useRef((props)=>{
    const changed = props.changed;
    changed.forEach(item => {
      const cell = cellRefs[item.key];
      
      console.log("CALLING IF"+ cell + "        " + item.key)
      if (cell) {
        if (item.isViewable) {
          console.log("PLAY OS CALLED")
          cell.play();
        } else {
          console.log("Pause is played")
          cell.pause();
        }
      }
    });
  });

  function loadItems(){

    const start = items.length;

    const newItems = initialItems.map((item, i) => ({
      ...item,
      id: start + i,
    }));

    const Litems = [...items, ...newItems];

    setItems( Litems );

  };

  function _renderItem({ item }){
    return (
      <Item
        ref={cellRefs[item.id]}
        {...item}
      />
    );
  };



    return (

      <View style={styles.container}>
        <FlatList
          style={{ flex: 1 }}
          data={items}
          renderItem={_renderItem}
          keyExtractor={item => item.id.toString()}
          onViewableItemsChanged={_onViewableItemsChanged.current}
          initialNumToRender={3}
          maxToRenderPerBatch={3}
          windowSize={5}
          getItemLayout={(_data, index) => ({
            length: cellHeight,
            offset: cellHeight * index,
            index,
          })}
          viewabilityConfig={viewabilityConfig}
          removeClippedSubviews={true}
          ListFooterComponent={
            <TouchableOpacity onPress={loadItems}>
              <Text style={{ padding: 30 }}>Load more</Text>
            </TouchableOpacity>
          }
        />
      </View>
    );
}



const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
  cell: {
    width: cellWidth - 20,
    height: cellHeight - 20,
    backgroundColor: '#eee',
    borderRadius: 20,
    overflow: 'hidden',
    margin: 10,
  },
  overlay: {
    position: 'absolute',
    top: 0,
    right: 0,
    bottom: 0,
    left: 0,
    backgroundColor: 'rgba(0,0,0,0.4)',
    padding: 40,
  },
  full: {
    position: 'absolute',
    top: 0,
    right: 0,
    bottom: 0,
    left: 0,
  },
  poster: {
    resizeMode: 'cover',
  },
  overlayText: {
    color: '#fff',
  },
});

最好是将源代码内联到堆栈溢出中,而不是将其保存在单独的链接中。 但是我查看了组件,我认为问题在于您如何使用道具。

在第 91 行,

export const FeedList: React.FC<FeedListProps> = ({}) => {

所以在这里,你需要获取 props 作为参数。 之前的 class 组件在this.props中可用。 但是在这里您需要按如下方式传递它,

export const FeedList: React.FC<FeedListProps> = (props) => {

或者你可以按如下方式分解道具,

export const FeedList: React.FC<FeedListProps> = ({changed}) => {

您还需要修改第 87 行的接口以反映类型。

应该足以使用功能组件并使用 useRef([]) 初始化为数组

工作示例: https : //snack.expo.io/2_xrzF!LZ

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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