【发布时间】:2021-08-12 18:59:25
【问题描述】:
作为标题,每次我使用<Redirect to="..."> 从一页重定向到另一页时,我都想滚动到顶部。本网站上现有的答案(尤其是这个热门话题:react-router scroll to top on every transition)都不起作用。
具体来说,我想要React 16.8+,功能组件,React Router V5-方法。我试过使用以下
const {path} = useRouteMatch()
实现下面的组件,作为整个<div className="App">的包装器,这样我就不用为每个想要这个效果的组件包装了:
ScrollToTop.js:
import {useEffect} from "react";
import {useRouteMatch} from "react-router-dom";
export const ScrollToTop = () => {
const {path} = useRouteMatch()
useEffect(() => {
console.log("path =", path)
window.scrollTo(0, 0)
}, [path])
return null
}
我正在做的部分工作:
import React, {useCallback, useEffect, useState} from "react";
import {ItemListPage} from "../../commons/ItemListPage/ItemListPage";
import {CreateButton} from "../../commons/buttons/CreateButton";
import CreateProblemModal from "../Modal/CreateProblemModal";
import {problemService} from "../../../services/services";
import {Spinner} from "../../commons/Spinner";
import {ProblemEditor} from "../ProblemEditor";
import {Link, Redirect, Route} from "react-router-dom";
import {TableCell} from "../../../utils/TableCell";
import {ProblemContext} from "./ProblemContext";
import {ScrollToTop} from "../../commons/scrolling/ScrollToTop";
export const useProblemList = () => {
const [problems, setProblems] = useState();
const addProblem = (problem) => {
problems.push(problem);
setProblems(problems);
};
return {problems, setProblems, addProblem}
};
const ProblemList = () => {
const [showCreateProblemModal, setShowCreateProblemModal] = useState(false)
const {problems, setProblems} = useProblemList();
const [currentProblem, setCurrentProblem] = useState();
const [shouldRedirect, setShouldRedirect] = useState(false)
const refetchProblem = useCallback((problemId) => {
problemService.getAllProblems()
.then(problems => {
setProblems(problems)
setCurrentProblem(problems.find(problem => parseInt(problem.id) === parseInt(problemId)))
})
}, [setProblems, setCurrentProblem])
useEffect(() => {
if (!problems || problems.length === 0) {
refetchProblem()
}
}, [problems, refetchProblem]);
const onProblemCreated = (problemId) => {
refetchProblem(problemId)
setShouldRedirect(true)
}
if (!problems || (shouldRedirect && !currentProblem)) {
return <Spinner/>
}
return (
<>
<ScrollToTop/>
{shouldRedirect?
<Redirect to={`problems/:problemId/edit`}/> : ""}
<Route path="/problems" exact>
<div className="problem-list font-poppins">
<div style={{paddingTop: "20px", paddingBottom: "150px"}}>
<div style={{display: "flex", justifyContent: "center"}}>
<ItemListPage title="Problem List"
width="1000px"
filterItems={["Filter", "Id", "tags"]}
Button={() =>
<CreateButton onClick={() => setShowCreateProblemModal(true)}/>}
tableHeaders={[
<TableCell>#</TableCell>,
<TableCell>Problem Title</TableCell>,
<TableCell>Tags</TableCell>
]}
tableRowGenerator={{
list: problems,
key: (problem) => problem.id,
data: (problem) => [
<TableCell>
<Link to={`/problems/${problem.id}/edit`}
onClick={() => setCurrentProblem(problem)}>
{problem.id}</Link>
</TableCell>,
<TableCell>
<Link to={`/problems/${problem.id}/edit`}
onClick={() => setCurrentProblem(problem)}>
{problem.title}</Link>
</TableCell>,
<TableCell>
<span className="tag is-link">Functions</span>
</TableCell>,
]
}}
tableDataStyle={{textAlign: "left"}}/>
<CreateProblemModal show={showCreateProblemModal}
onClose={() => setShowCreateProblemModal(false)}
onProblemCreated={onProblemCreated}/>
</div>
</div>
</div>
</Route>
<Route path="/problems/:problemId/edit">
<ProblemContext.Provider value={{
currentProblem, setCurrentProblem, refetchProblem, setShouldRedirect}}>
<ProblemEditor/>
</ProblemContext.Provider>
</Route>
</>
)
}
export {ProblemList};
【问题讨论】:
-
你是说上面的代码 sn-p 不起作用?或者您希望它仅在组件首次安装时才滚动到顶部?
-
@Tolumide:感谢您尝试帮助我。我的帖子中的一个只是其中之一作为示例。我想在每次 URL 更改时滚动到顶部,通过鼠标单击或 react-router-dom 提供的
<Redirect to="...">。 -
例如:我有一个包含所有问题的 ProblemList,我必须滚动页面才能看到列表末尾附近的问题。当我单击其中一个的标题时,它将导航到我可以编辑问题的页面,而屏幕在中间 onEnter 我想要的是它从顶部开始。
-
问题已解决:删除
overflow-y: auto。
标签: reactjs react-router react-router-dom