简体   繁体   English

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

[英]Basic react native question covert Class to Function

It might sound silly but I am just learning here I am trying to convert a component to a function-based component.这可能听起来很傻,但我只是在这里学习我正在尝试将组件转换为基于函数的组件。 I did everything right but I am stuck on something very silly我做的一切都是正确的,但我被困在一些非常愚蠢的事情上

I have this code for Discover我有这个发现代码

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

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

what is the correct way to convert cellRefs to work with the function I have?将 cellRefs 转换为使用我拥有的功能的正确方法是什么? I tried everything when I do this in my class file it is fine it gives me an object with the things I need.当我在我的类文件中执行此操作时,我尝试了所有方法,这很好,它为我提供了一个包含我需要的东西的对象。

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

However,然而,

const cell = cellRefs[item.key];

is just giving undefined只是给 undefined

Full code for the converted component转换后的组件的完整代码

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',
  },
});

It would be best if you could inline your source code into stack overflow, than keeping it in a separate link.最好是将源代码内联到堆栈溢出中,而不是将其保存在单独的链接中。 However I took a look at the component, and I think the issue is with how you are using props.但是我查看了组件,我认为问题在于您如何使用道具。

On line 91,在第 91 行,

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

So here, you need to get the props as an argument.所以在这里,你需要获取 props 作为参数。 Earlier with the class component it was available at this.props .之前的 class 组件在this.props中可用。 However here you need to pass it as below,但是在这里您需要按如下方式传递它,

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

Or you may destructure the props as below,或者你可以按如下方式分解道具,

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

You will also need to modify the interface on line 87 to reflect the type.您还需要修改第 87 行的接口以反映类型。

Should be enough to use a functional component and use useRef([]) initialized as an array应该足以使用功能组件并使用 useRef([]) 初始化为数组

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

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

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