【问题标题】:Delay after prepending elements to a list and scroll to same scrolling view将元素添加到列表并滚动到相同的滚动视图后延迟
【发布时间】:2021-09-10 23:08:36
【问题描述】:

当您滚动到列表中的某个位置并按“空格”时,新元素将添加到列表中。代码意图是保持与用户按下“空格”之前相同的滚动视图。加载项目并在几毫秒内,滚动视图位于新前置项目的顶部,然后滚动到保存的先前滚动视图。我想立即制作它,而不会出现让用户烦恼的毫秒延迟。

能买到吗?

代码:

import React, { useState, useEffect, useRef } from "react";
import "./styles.css";

export default function App() {
  const listRefs = useRef({});
  const scrollRef = useRef();
  const oldListHeight = useRef();

  const generateId = (length) => {
    let result = "";
    const characters =
      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    const charactersLength = characters.length;
    for (let i = 0; i < length; i++) {
      result += characters.charAt(Math.floor(Math.random() * charactersLength));
    }
    return result;
  };

  const generateList = () => {
    const html = [];

    for (let i = 0; i < Math.floor(Math.random() * 30) + 20; i++) {
      const id = generateId(15);

      listRefs.current[id] = React.createRef();
      html.push(
        <li ref={listRefs[id]} key={id}>
          {id}
        </li>
      );
    }

    return html;
  };

  const [htmlList, setHtmlList] = useState(generateList());

  useEffect(() => {
    setTimeout(() => {
      const listHeightDiff =
        scrollRef.current.scrollHeight - oldListHeight.current;
      scrollRef.current.scrollTo({
        top: scrollRef.current.scrollTop + listHeightDiff
      });
    }, 0);
  }, [htmlList]);

  useEffect(() => {
    window.addEventListener("keydown", handleKeyDown, false);

    return () => {
      window.removeEventListener("keydown", handleKeyDown, false);
    };
  }, []);

  const handleKeyDown = (e) => {
    if (e.key === " ") {
      oldListHeight.current = scrollRef.current.scrollHeight;
      setHtmlList((htmlList) => [generateList(), ...htmlList]);
    }
  };

  return (
    <div className="App">
      <div ref={scrollRef} className="wrapper">
        <ul>{htmlList}</ul>
      </div>
    </div>
  );
}

游乐场:

https://codesandbox.io/s/affectionate-antonelli-wkvvd?file=/src/App.js

【问题讨论】:

  • 你的问题不是很清楚。您是想说htmlList 一次又一次地加载所有内容,并在您不断添加越来越多的内容时造成一点延迟?
  • 进入 Playground,按几次“空格键”创建一个大的可滚动列表。然后滚动到一个位置并按“空格键”。您会看到新列表收费的延迟,然后滚动到最后一个视图。这不是立即的,我希望在没有那个小延迟的情况下获得相同的结果。
  • 说实话,它就像一个魅力。即使在您的 CodeSandbox 中尝试,我也无法重现您遇到的问题
  • 我制作了一个视频来向您展示这个问题。检查添加新列表时的小延迟:files.fm/f/8wd9k4h38
  • 检查更新的代码和答案。

标签: javascript reactjs scroll


【解决方案1】:

我认为这是问题所在,

你的setHtmlList((htmlList) =&gt; [generateList(), ...htmlList]);

generateList() 返回一个数组,因此您的数组变为 [[some ids],oldids],

它变成了一个数组数组,React 重新渲染所有内容。你需要的是[新ID,旧ID]。

要修复它,我必须将上面的行更改为

setHtmlList((htmlList) =&gt; [...generateList(), ...htmlList]);

注意generateList() 上的扩展运算符。这将使数组变平,而 React 可以管理其余部分。

更新代码,

https://codesandbox.io/s/eloquent-cherry-6hxyo?file=/src/App.js:1572-1633

【讨论】:

    猜你喜欢
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多