[英]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.