我正在开发一个MERN应用程序,人们可以在其中添加用户创建的内容。我已经合并了基本的加载功能,以便在从服务器获取数据时向用户提供反馈。但是,我希望能够进行一些改进以提高性能并减少加载时间。
我目前的做法:
作为示例,我将解释我的PostComponent,它将通过分派的redux动作(getPosts)从数据库请求用户创建的帖子。这些帖子呈现在子组件PostFeed中,然后映射到各个PostItem组件中。
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import PostForm from './PostForm';
import PostFeed from './PostFeed';
import Spinner from '../common/Spinner';
import { getPosts } from '../../actions/postActions';
class Posts extends Component {
componentDidMount() {
this.props.getPosts();
}
render() {
const { posts, loading } = this.props.post;
let postContent;
if (posts === null || loading) {
postContent = <Spinner />;
} else {
postContent = <PostFeed posts={posts} />;
}
return (
<div className="feed">
<div className="container">
<div className="row">
<div className="col-md-12">
<PostForm />
{postContent}
</div>
</div>
</div>
</div>
);
}
}
Posts.propTypes = {
getPosts: PropTypes.func.isRequired,
post: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
post: state.post,
});
export default connect(mapStateToProps, { getPosts })(Posts);
在帖子发布之前,我将布尔加载设置为true
。获取所有帖子后,将加载再次设置为false
。上面组件中的if
语句正在渲染一个微调器,它是一个.gif文件或PostFeed组件,具体取决于加载布尔值的状态。
postActions:
...
export const setPostLoading = () => {
return {
type: POST_LOADING,
};
};
export const getPosts = () => (dispatch) => {
dispatch(setPostLoading());
axios
.get('/api/posts')
.then(res => dispatch({
type: GET_POSTS,
payload: res.data,
}))
.catch(err => dispatch({
type: GET_POSTS,
payload: null,
}));
};
...
postReducer:
...
export default function (state = initialState, action) {
switch (action.type) {
case POST_LOADING:
return {
...state,
loading: true,
};
case GET_POSTS:
return {
...state,
posts: action.payload,
loading: false,
};
...
这一切都可以正常工作,但是我对此方法有两个担忧:
首先,在加载组件时使用微调器会使事情在页面上有些跳动。虽然不一定是一件坏事,但我想创造最无缝的用户体验,并发现实现占位符是一种更优雅的解决方案。
如何为每个单独的组件实现占位符项,以使内容在加载时不会跳动并保持良好位置?
第二,加载帖子时,它正在加载存储在数据库中的所有可用帖子。我可以想象,当发布过多的帖子时,加载所有单个PostItem可能会花费很长时间,并且会占用很多不必要的带宽。
如何添加仅加载浏览器窗口中显示的内容的功能,以便在用户向下滚动时加载更多内容?可能是滚动事件处理程序?但是,如何确定要渲染哪个PostItem以及保留哪个占位符?
希望我已经解释得很清楚了,它仍然是相对较新的反应/ redux,因此这里可能会出现一些错误。欢迎任何提示,建议或最佳做法。
非常感谢!
答案 0 :(得分:1)
您在这里问了很多问题。首先,听起来您已经需要为每个组件显示“骨架”,并且好消息是有多种解决方案可用,例如react-content-loader使用可定制的SVG,react-placeholder ,(或者您可以使用react-transition-group进行滚动。文档将说明如何根据需要管理每个组件的过渡。
关于从axios API调用返回的项目“过多”,如果不知道一个粗糙的数字(100、1000,更多等),并且发现性能问题,就很难说。您要返回多少数据。如果数字最终有问题,那么您所寻找的就是“虚拟(或无限)滚动”和分页,即您不是一次请求所有数据,而是成块请求。例如,StackOverflow使用分页,新的Reddit使用无限滚动。同样,也有NPM软件包,例如react-tiny-virtual-list。