javascript - 防止在获取和附加项目后将 react-waypoint 滚动位置重置为顶部

标签 javascript reactjs scrollview lazy-loading jquery-waypoints

我有一个结构如下的组件。一旦用户到达卡片集合的末尾,它使用 react-waypoint 来获取和呈现额外的卡片。

componentDidMount() {
    const { actions, user } = this.props;
    if (!user) return;
    actions.getConnections(user.guid, 0, DEFAULT_FETCH_ROW_COUNT)
        .then(({ data }) => {
            this.setState({
                fullyLoaded: data.length < DEFAULT_FETCH_ROW_COUNT,
                firstLoaded: true
            });
        });
}

loadMoreConnections(rows = DEFAULT_FETCH_ROW_COUNT) {
    const { user, connections, actions } = this.props;
    const { fullyLoaded } = this.state;

    if (fullyLoaded) return;
    return actions.getConnections(user.guid, connections.length, rows, true)
        .then(({ data }) => {
            this.setState({
                fullyLoaded: data.length < rows
            });
        });
}

showConnections() {
    const { user, connections, actions } = this.props;
    return (
        connections.map((connection, index) => (
            <div className="col-12 col-md-6 col-lg-4 col-xl-3 card-wrapper" key={index}>
                {(!this.state.fullyLoaded && index === (connections.length - THRESHOLD)) && (index >= DEFAULT_FETCH_ROW_COUNT - THRESHOLD) && (
                    <Waypoint
                        onEnter={() => {
                            this.loadMoreConnections();
                        }}
                    />
                )}
                <Link
                    id={`${idPrefix}ConnectionCardLink${index}`}
                    to={`/${ROUTES.PROFILE}/${getProfileUrl(connection)}`}
                >
                    <ConnectionCard
                        idPrefix={idPrefix}
                        src={connection.photo ? connection.photo.url : ''}
                        idSuffix={index}
                    >
                        <h5 id={`${idPrefix}NameTxt${index}`}
                            className="text-truncate font-weight-bold">{connection.firstname} {connection.lastname}</h5>
                        <h6 id={`${idPrefix}PrimaryJobTxt${index}`}
                            className="text-truncate text-secondary primary-job">
                            {connection.primaryWorkHistory
                                ? (
                                    `${connection.primaryWorkHistory.jobs[0].jobName} @ ${connection.primaryWorkHistory.employer.name}`
                                    + `${connection.primaryWorkHistory.employer.location
                                        ? `, ${connection.primaryWorkHistory.employer.location.city}, ${connection.primaryWorkHistory.employer.location.state}`
                                        : '' }`
                                )
                                : ' '
                            }
                        </h6>
                        <div className="button-group">
                            <Link
                                id={`${idPrefix}ViewProfileBtn${index}`}
                                className="button hollow small"
                                to={`/${ROUTES.PROFILE}/${getProfileUrl(connection)}`}
                            >
                                View Profile
                            </Link>
                            <Button
                                id={`${idPrefix}MessageBtn${index}`}
                                className="small"
                                label="Message"
                                onClick={(e) => {
                                    e.preventDefault();
                                    actions.openChatByParticipants(user, connection);
                                }}
                            />
                        </div>
                    </ConnectionCard>
                </Link>
            </div>
        ))
    );
}

showNoResults() {
    return (
        <EmptySearchResults
            idPrefix={`${idPrefix}EmptySearch`}
            title="Don’t be shy."
            description="It looks like you don’t have any connections, but don’t worry you can search our community."
        >
            <Link
                id={`${idPrefix}GetConnectedBtn`}
                className="button action-button"
                to={`/${ROUTES.COMMUNITY}/suggested`}
            >
                Get Connected
            </Link>
        </EmptySearchResults>
    )
}

render() {
    const { connections, isFetchingConnections } = this.props;
    const { firstLoaded } = this.state;
    let view = null;

    if (connections.length) {
        view = this.showConnections();
    } else if (firstLoaded) {
        view = this.showNoResults();
    }

    return (
        <div className="row">
            {view}
        </div>
    );
}

这按预期工作,但我想在获取和呈现此附加数据时显示加载程序组件。为此,我尝试通过添加/修改以下内容来实现加载器组件:

showLoader() {
    return (
        <div className="select-overlay-loader d-flex justify-content-center align-items-center">
            <Loader />
        </div>
    );
}

if(isFetchingConnections) {
        view = this.showLoader();
    } else if (connections.length) {
        view = this.showConnections();
    } else if (firstLoaded) {
        view = this.showNoResults();
    }

这些更改确实会在获取和显示更多卡片数据时显示加载器组件,但在将新卡片附加到列表后,列表的 ScrollView 会重置到顶部。我不确定如何在获取之间保留列表的滚动位置。

我看过类似问题的答案,例如 one

建议在获取新数据之前将列表的 scrollTop 设置为列表的当前 scrollHeght。

我已经尝试过,但未能实现此修复。

组件放置的问题?我见过将 放置在渲染列表末尾的示例,但在这种情况下, map 函数中每个卡片组件的顶部都包含一个组件。

我正在处理现有的代码库并且是 React 的新手,所以请原谅我的任何无知。我希望我的问题已清楚地提出。

谁能指出我正确的方向?

干杯!

最佳答案

为了在 React.js 中实现反向无限滚动,你需要做这样的事情:

componentWillUpdate() {
    this.scrollHeight = this.scrollableElement.scrollHeight;
    this.scrollTop = this.scrollableElement.scrollTop;
}

componentDidUpdate() {
    this.scrollableElement.scrollTop = this.scrollTop +
        (this.scrollableElement.scrollHeight - this.scrollHeight);
}

在每次更新之前你存储最后的滚动位置,更新之后你只需恢复它。它确实对我有用。在我的例子中,一个航路点组件被放置在顶部。

我在这里找到了这个解决方案:http://blog.vjeux.com/2013/javascript/scroll-position-with-react.html .

关于javascript - 防止在获取和附加项目后将 react-waypoint 滚动位置重置为顶部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45777905/

相关文章:

android - Action 发生后将焦点设置在 ScrollView 的顶部android

javascript - 当用户点击父 div 时点击按钮

javascript - 不改变 "left"属性的可调整大小的 div

css - 对鼠标悬停建议使用react

reactjs - 如何将一个组件设置为位于另一个组件下的样式?

javascript - 如何使用按钮重新加载 YUI ScrollView 的内容?

javascript - 将参数传递给 javascript 文件,它是如何工作的?

javascript - 如何删除包含所有空值的数组列?

javascript - ReactJS/JavaScript 在对象中查找数组

android - 如何在 android 中使用 ScrollView 固定页脚?