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



这是我正在处理的:

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

我的意思是,React 很快,但我的新组件需要一段时间才能渲染,因为它是一个全新的页面。所以它应该需要 200 到 400 毫秒。如果我没有得到 UI 反馈,感觉我的点击不起作用。

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

理论上,CSS可以使用以下方法进行处理:

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

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

注意:这不是移动设备上等待双击的 300 毫秒默认延迟。我已经使用适当的标签处理了这个问题。

我想做的是:

  • 停止使用<Link/>组件并使用普通<a/>
  • 创建要在click事件后更新的clicked状态
  • 调用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>
);
}

您应该使用两个loading阶段。

  1. 使用懒惰 装载 加载"繁重"页面并显示 骨架 组件作为回退,向用户显示某些内容正在加载。
  2. 使用组件/redux 状态加载指示器来表示您的页面何时 从 API 加载数据

试图通过 react-router 链接来实现这一点并不是最好的方法,因为路由会立即发生,它不是阻碍应用程序的原因。API 调用和多次重新呈现会导致应用程序运行缓慢。

最新更新