单击 react-router-dom <Link/> 后的用户 UI 反馈?

Posted

技术标签:

【中文标题】单击 react-router-dom <Link/> 后的用户 UI 反馈?【英文标题】:User UI feedback after clicking on a react-router-dom <Link/>? 【发布时间】: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>
  );


【问题讨论】:

【参考方案1】:

您应该使用两个loading 阶段。

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

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

【讨论】:

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

以上是关于单击 react-router-dom <Link/> 后的用户 UI 反馈?的主要内容,如果未能解决你的问题,请参考以下文章

单击按钮以重定向到父 URL

如何防止某人被在某些情况下从react-router-dom重定向

使用 react-router-dom 停止页面中侧边栏的重新渲染

React - 单击按钮转到视口顶部

react-router-dom `history`:无法读取未定义的属性“推送”

页眉/页脚导航 react-router-dom 和 antd 菜单和路由器问题