【问题标题】:User UI feedback after clicking on a react-router-dom <Link/>?单击 react-router-dom <Link/> 后的用户 UI 反馈?
【发布时间】:2020-08-29 14:14:27
【问题描述】:

这是我正在处理的:

  • 使用react + react-router-dom 构建的单页应用程序
  • 用户点击&lt;Link to={"/new-page-route"}/&gt;
  • URL 更改,我的&lt;Route/&gt; 开始呈现新的&lt;Component/&gt;

我的意思是,React 很快,但我的新组件需要一段时间才能呈现,因为它是一个全新的页面。所以它应该在 200 到 400 毫秒之间。如果我没有收到 UI 反馈,就感觉我的点击没有成功。

我需要某种 UI 反馈,以便我的用户知道他们的点击已被触发并且正在发生某些事情。我认为我不需要加载器或其他任何东西,但需要一些东西来表明用户界面“接受”了点击。

理论上可以通过 CSS 处理:

  • -webkit-tap-highlight-color: #SOMECOLOR
  • active: #SOMECOLOR

但不知何故,当 URL 更改并且新的渲染开始时,浏览器无法将这些 CSS 结果绘制到屏幕上,至少 Chrome 和 Firefox 上会出现这种情况。有点奇怪,有时我会看到tap-highlightactive-change,但几乎总是我看不到。

注意:这不是等待双击的300ms default delay on mobile。我已经使用适当的标签处理了这个问题。

我想做的是:

  • 停止使用&lt;Link/&gt; 组件并使用普通的&lt;a/&gt;
  • 创建clicked 状态以在click 事件之后更新
  • 调用event.preventDefault() 以防止&lt;a/&gt; 导航的正常行为
  • 使用clicked 状态为 UI 反馈呈现一些新样式
  • clicked 状态变为真后,在useEffect 上触发history.push("/new-page-route")

类似:

const newUrl = "/new-page-route";
const [clicked,setClicked] = useState(false);

const history = useHistory();      // HOOK FROM react-router-dom

function handleLinkClick(event) {
  event.preventDefault();
  setClicked(true);
}

useEffect(() => {

  if (clicked === true) {

    history.push(newUrl);

    // OR MAYBE ADD A TIMEOUT TO BE EXTRA SURE THAT THE FEEDBACK WILL BE PAINTED
    // BECAUSE I'VE SEEN THE BROWSER NOT BEING ABLE TO PAINT IF I DON'T GIVE IT SOME EXTRA TIME
    setTimeout(() => history.push(newUrl),100);

  }

},[clicked,history]);


// USE THE clicked STATE TO RENDER THE UI FEEDBACK (CHANGE TEXT COLOR, WHATEVER I NEED);

问题

以前有人遇到过这个问题吗?解决这个问题的好方法是什么?我猜理论上浏览器应该能够在新渲染开始之前进行绘制,但这不是我得到的。

有问题的沙盒

https://codesandbox.io/s/nice-monad-4fwoc

https://4fwoc.csb.app

  • 在桌面上:单击链接时,我可以看到active 状态的BLUE 背景
  • 在移动设备上:单击链接时我没有看到任何 CSS 更改。除非我点按并按住
  • 评论:假设您的组件需要一段时间才能呈现。没有任何 UI 反馈,感觉根本没有点击,即使是在后台渲染。
import React from "react";
import { Link, Switch, Route } from "react-router-dom";
import styled from "styled-components";
import "./styles.css";

const HOME = "/";
const ROUTE1 = "/route1";
const ROUTE2 = "/route2";

const LS = {};

// REGULAR CSS RULES FOR THE className="link" ARE ON "./styles.css"

LS.Link_LINK = styled(Link)`
  color: black;
  -webkit-tap-highlight-color: red;
  &:active {
    background-color: blue;
  }
`;

export default function App() {
  return (
    <React.Fragment>
      <div>
        <Switch>
          <Route exact path={HOME} component={Home} />
          <Route exact path={ROUTE1} component={Component1} />
          <Route exact path={ROUTE2} component={Component2} />
        </Switch>
      </div>
    </React.Fragment>
  );
}

function Home() {
  return (
    <React.Fragment>
      <div>I am Home</div>
      <LS.Link_LINK to={ROUTE1}>Route 1 (using styled-components)</LS.Link_LINK>
      <br />
      <Link className={"link"} to={ROUTE1}>
        Route 1 (using regular CSS)
      </Link>
    </React.Fragment>
  );
}

function Component1() {
  return (
    <React.Fragment>
      <div>I am Component1</div>
      <LS.Link_LINK to={ROUTE2}>Route 2 (using styled-components)</LS.Link_LINK>
      <br />
      <Link className={"link"} to={ROUTE2}>
        Route 2 (using regular CSS)
      </Link>
    </React.Fragment>
  );
}

function Component2() {
  return (
    <React.Fragment>
      <div>I am Component2</div>
      <LS.Link_LINK to={HOME}>Home (using styled-components)</LS.Link_LINK>
      <br />
      <Link className={"link"} to={HOME}>
        Home (using regular CSS)
      </Link>
    </React.Fragment>
  );
}

【问题讨论】:

    标签: javascript css reactjs react-router styled-components


    【解决方案1】:

    您应该使用两个loading 阶段。

    1. 使用lazy loading 加载“重”页面并显示 skeleton 组件作为后备,以向用户显示正在加载的内容。
    2. 使用组件/redux 状态加载指示器来指示您的页面何时 从 api 加载数据

    尝试使用 react-router 链接来实现这一点并不是最好的方法,因为路由会立即发生,它不会让您的应用程序停滞不前。 Api 调用和多次重新渲染会导致应用程序运行缓慢。

    【讨论】:

    • 谢谢,塔索斯。在此路由更改期间没有调用任何 API。但是它渲染了多个组件,渲染了多个下拉列表,还有 svg 图表和其他一些东西,所以需要一段时间。更改路线时已存在的所有数据。这不是一个巨大的延迟。它仍然比从服务器获取页面快得多,我可以让用户等待 200-400 毫秒。我只需要清楚他的点击被“接受”并且正在被“处理”,或者类似的东西。这就是为什么我想到tap-highlight 或其他东西的原因。但它不起作用。
    • 这只是移动设备上的问题,CPU 功率较小。在桌面上,页面更改基本上是实时的,所以我不需要点击反馈。反馈是页面更改本身。我认为如果我要为此实现延迟加载和多个渲染级联,我会不必要地增加额外的复杂性。特别是不涉及 API 调用。你怎么看?
    • 由于 url 更改并且正在加载一个新组件,您无法做太多事情,对您有用的是 npmjs.com/package/react-redux-loading-bar,我还发现这可能对您有所帮助:stackoverflow.com/a/40989121/5605822
    猜你喜欢
    • 2020-11-22
    • 1970-01-01
    • 2019-08-27
    • 2023-03-16
    • 2021-01-28
    • 2021-05-07
    • 2021-09-27
    • 2019-11-25
    • 2020-04-29
    相关资源
    最近更新 更多