【发布时间】:2019-04-19 17:18:46
【问题描述】:
在我的 React Native Expo 项目中,我创建了一个调用自身的递归注释组件,以呈现嵌套的注释线程。
但是,一旦 cmets 的数量太大,性能就会开始下降,因为它对用户不是很友好。我尝试改变 api 调用的结构以检索该 cmets 和一些其他小的调整,但无济于事.
我认为我需要以某种方式使用 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));
【问题讨论】:
-
限制递归迭代的数量并将其余部分隐藏在“查看更多”后面
-
是的,我已经考虑过了。临时修复可能不是一个坏主意,但从长远来看,用户体验不会那么好..
-
为什么不呢?大多数大型网站都以某种方式合并了这一点 - facebook、twitter,甚至 stackoverflow
-
确实如此。我肯定会保留它作为一个选项。我更喜欢类似于 FlatList 组件的无限滚动。
-
这是一篇关于为什么无限滚动可能是一个坏主意的好文章:logrocket.com/blog/infinite-scroll
标签: javascript reactjs react-native