单击 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
构建的单页应用程序
用户点击<Link to="/new-page-route"/>
URL 更改,我的<Route/>
开始呈现新的<Component/>
我的意思是,React 很快,但我的新组件需要一段时间才能呈现,因为它是一个全新的页面。所以它应该在 200 到 400 毫秒之间。如果我没有收到 UI 反馈,就感觉我的点击没有成功。
我需要某种 UI 反馈,以便我的用户知道他们的点击已被触发并且正在发生某些事情。我认为我不需要加载器或其他任何东西,但需要一些东西来表明用户界面“接受”了点击。
理论上可以通过 CSS 处理:
-webkit-tap-highlight-color: #SOMECOLOR
active: #SOMECOLOR
但不知何故,当 URL 更改并且新的渲染开始时,浏览器无法将这些 CSS 结果绘制到屏幕上,至少 Chrome 和 Firefox 上会出现这种情况。有点奇怪,有时我会看到tap-highlight
和active-change
,但几乎总是我看不到。
注意:这不是等待双击的300ms default delay on mobile。我已经使用适当的标签处理了这个问题。
我想做的是:
停止使用<Link/>
组件并使用普通的<a/>
。
创建clicked
状态以在click
事件之后更新
调用event.preventDefault()
以防止<a/>
导航的正常行为
使用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 反馈?的主要内容,如果未能解决你的问题,请参考以下文章
如何防止某人被在某些情况下从react-router-dom重定向
使用 react-router-dom 停止页面中侧边栏的重新渲染