【发布时间】: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: #SOMECOLORactive: #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
- 在桌面上:单击链接时,我可以看到
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