![](/img/trans.png)
[英]How do we improve the performance of a react application which renders the the deep nested tree data with a recursive component
[英]How can I improve the performance of a recursive component in React?
在我的React Native Expo項目中,我創建了一個自我調用的遞歸注釋組件,以呈現嵌套的注釋線程。
但是,一旦評論的數量變得太大,性能開始降低,它不是非常用戶友好。我已經嘗試改變api如何調用檢索該評論和其他一些小調整的結構,但無濟於事。
我想我需要以某種方式使用shouldComponentUpdate,只在某些狀態發生變化時才重新渲染,主要是注釋是打開還是折疊。
有沒有辦法提高React中遞歸組件的性能?
import { FontAwesome } from "@expo/vector-icons";
import dateFns from "date-fns";
import { inject } from "mobx-react";
import PropTypes from "prop-types";
import React from "react";
import {
ActivityIndicator,
StyleSheet,
TouchableHighlight,
View
} from "react-native";
import Collapsible from "react-native-collapsible";
import HTMLView from "react-native-htmlview";
import { Text, withTheme } from "react-native-paper";
import ApiService from "../services/ApiService";
class Comment extends React.Component {
static propTypes = {
api: PropTypes.instanceOf(ApiService).isRequired,
commentIds: PropTypes.arrayOf(PropTypes.number).isRequired
};
state = {
comments: null
};
componentDidMount() {
this.fetchStoryComments();
}
async fetchStoryComments() {
const { api, commentIds } = this.props;
try {
let comments = await api.fetchStoryComments(commentIds);
comments = comments.map(comment => {
const commentCopy = comment;
commentCopy.isCollapsed = false;
return commentCopy;
});
this.setState({
comments
});
} catch (error) {
// HANDLE ERROR
}
}
toggleCollapse(commentId) {
this.setState(prevState => ({
comments: prevState.comments.map(comment =>
comment.id === commentId
? Object.assign(comment, { isCollapsed: !comment.isCollapsed })
: comment
)
}));
}
render() {
const { comments } = this.state;
const { api } = this.props;
return comments ? (
comments.map(
comment =>
comment && (
<View key={comment.id} style={styles.commentContainer}>
<TouchableHighlight
onPress={() => this.toggleCollapse(comment.id)}
>
<View style={styles.commentHeader}>
<Text style={styles.commentHeaderText}>
{`${comment.by} ${dateFns.distanceInWordsToNow(
new Date(comment.time * 1000)
)} ago`}
</Text>
<Text style={styles.commentHeaderText}>
{comment.isCollapsed ? (
<FontAwesome name="plus" />
) : (
<FontAwesome name="minus" />
)}
</Text>
</View>
</TouchableHighlight>
<Collapsible duration={200} collapsed={comment.isCollapsed}>
<View style={styles.comment}>
<HTMLView
addLineBreaks={false}
stylesheet={htmlStyles}
textComponentProps={{ style: styles.commentText }}
value={comment.text}
/>
{"kids" in comment && (
<View style={styles.kids}>
<Comment api={api} commentIds={comment.kids} />
</View>
)}
</View>
</Collapsible>
</View>
)
)
) : (
<ActivityIndicator
style={styles.activityIndicator}
size="small"
color="#fff"
/>
);
}
}
export default inject("api")(withTheme(Comment));
你嘗試過使用平面列表而不是映射一堆視圖嗎?
這是一個解釋如何使用它的指南 。
編輯1:
實際上,你可以使用一個sectionlist這就好比flatlist像你正在建設一個復雜的結構。
這是一個小例子:
render() {
const a = ['comment 1 a', 'comment 2 a', 'comment 3 a'];
const b = ['comment 1 b', 'comment 2 b'];
const c = ['comment 1 c'];
return (
<View style={{ marginTop : (Platform.OS) == 'ios' ? 20 : 0 }}>
<SectionList
sections={[
{ comment: 'Comment a with subcomponents a', data: a },
{ comment: 'Comment b with subcomponents b', data: b },
{ comment: 'Comment c with subcomponents c', data: c },
]}
renderSectionHeader={ ({section}) => <Text> { section.comment } </Text> }
renderItem={ ({item}) => <Text> { item } </Text> }
keyExtractor={ (item, index) => index }
/>
</View>
);
}
部分列表中的data
字段可以是組件數組,希望對此有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.