我正在使用React Native在音乐应用程序中工作,在主屏幕中,我使一个类组件包含了四个以上的FlatList,并且它是从API中获取数据“它是大数据”,
因此我为此创建了一个函数,并将其放在componentDidMount()中,
但是我注意到,当我在setState之后记录数据时,在RN-Debugger中看到它两次以上
那么我该如何防止这种情况发生? 因为它会影响性能:)
这是我的代码段
class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
url: '******',
loading: false,
minimal: false,
MiniURL: '',
songName: '',
currentTrackIndex: 0,
isPlaying: true,
};
}
getRecentSongs = async () => {
try {
let response = await API.get('/index');
let {recent_tracks} = response.data.data;
let recent_tunes = [];
recent_tracks.map(track =>
recent_tunes.push({
id: track.id,
name: track.name,
url: this.state.url + track.sounds,
img: this.state.url + track.avatar,
}),
);
let data = response.data.data;
this.setState({data, recent_tunes, loading: true}, () =>
console.log('data', this.state.data),
);
} catch (error) {
console.log(error);
this.setState({error: true});
}
};
componentDidMount() {
this.getRecentSongs();
}
_renderItem = ({item, index}) => {
const {url} = this.state;
return (
<TouchableNativeFeed
key={item.id}
onPress={() => {
this.props.navigation.navigate({
key: 'Player',
routeName: 'Player',
params: {
tunes: this.state.recent_tunes,
currentTrackIndex: index,
},
});
}}
background={TouchableNativeFeedback.Ripple('white')}
delayPressIn={0}
useForeground>
<Card style={styles.card} noShadow={true}>
<FastImage
style={{width: 200, height: 200}}
source={{uri: url + item.avatar}}
resizeMode={FastImage.resizeMode.cover}
style={styles.cardImg}
/>
<Body style={styles.cardItem}>
<View style={styles.radioCardName}>
<View style={styles.cardViewFlex}>
<Text style={styles.text}>{item.name}</Text>
</View>
</View>
</Body>
</Card>
</TouchableNativeFeed>
);
};
render(){
const {data} = this.state;
return(
...
{/* Recent Songs Here*/}
<View style={{marginVertical: 10}}>
<FlatList
horizontal={true}
showsHorizontalScrollIndicator={false}
data={data.recent_tracks}
contentContainerStyle={{flexGrow: 1}}
ListEmptyComponent={<EmptyList />}
keyExtractor={(track, index) => track.id.toString()}
// initialNumToRender={10}
renderItem={this._renderItem}
/>
</View>
...
)
}
}
答案 0 :(得分:0)
很难从发布的内容中看出来,但是其中一个组件的键是否可能比您期望的更频繁地更改?如果检测到任何关键更改,React将触发完全重新渲染。
答案 1 :(得分:0)
ComponentDidMount将仅执行一次,并在删除后卸载。因此,这意味着它在应用程序的某些部分被创建了两次。
我遇到了类似的问题,并且与我的导航库有关,就我而言,我使用的是反应导航https://github.com/react-navigation/react-navigation/issues/2599。
因此,我建议您检查创建组件时是否发生了某些事情,以及是否执行了两次。另外,请仔细检查您的导航是否执行相同的操作。
答案 2 :(得分:0)
请使用React.memo
在道具中没有任何相关数据的情况下,它将不会重新渲染组件。
例如:
/**Your render item*/
const AddsItem = React.memo(({item, index}) => {
return (
<TouchableNativeFeed
...
...
</TouchableNativeFeed>
);
});
/**Your class*/
class Home extends React.Component {
constructor(props) {
...
}
render(){
const {data} = this.state;
return(
...
...
...
)
}