我的应用程序中有2条路线,/validations
(这是一个列表)和/validations/:id
(这是针对特定项目的同一列表)。
我最初静态地写了我的路线,并且一切正常(如预期):
<Route path="/validations/:id" component={Validations} />
<Route path="/validations" component={Validations} />
但是,由于我想进行一些重构,因此将路由放入数组中,并使用.map
来呈现它们。但是有了这个,当我单击一个项目时,整个页面将重新呈现,并且丢失了列表的滚动(这对用户来说是一个糟糕的用户体验,因为他失去了列表中的位置):
const routes = [
{
path: '/validations/:id',
component: Validations,
},
{
path: '/validations',
component: Validations,
},
]
// ...and in the JSX...
{routes.map(({ path, component }) => (
<Route
key={path}
path={path}
component={component}
/>
))}
即使是陌生人,如果我移除了key
的{{1}}道具,我也会恢复到最初的行为(但是我有React的警告)。
我写错了吗?它是React-Router的错误吗?一个反应堆?
如何在路由映射中保持列表滚动?
答案 0 :(得分:2)
我知道有些东西可疑,因为我已经做了很多次,但没有得到您的结果。因此,我注意到您在侧边内部中渲染了侧边栏。
这就是为什么它要重新渲染并将所有内容设置为顶部的原因。因为您实际上导航到另一条路线。
您需要做的是将边栏链接设置为外部实际路线,但内部 路由器组件。
类似于此沙箱:https://codesandbox.io/s/p2r4pl2o3q
如果您发现我稍微改变了路线:
const routes = [
{
path: "/",
component: Index
},
{
exact: true,
path: "/validations",
component: Validations
},
{
path: "/validations/:id",
component: Validations
}
];
然后创建侧边栏组件并将其设置在路线之外
<BrowserRouter>
<div>
<Sidebar />
<div style={{ marginLeft: 150 }}>{routeComponents}</div>
</div>
</BrowserRouter>
侧边栏:
var items = Array.apply(null, Array(300)).map(function(x, i) {
return i;
});
export default () => (
<div
style={{
width: 150,
height: "100vh",
display: "flex",
overflow: "auto",
position: "absolute",
flexDirection: "column"
}}
>
{items.map((item, index) => (
<Link to={`/validations/${index}`} key={index}>
Item {index}
</Link>
))}
</div>
);
现在,自第一次单击以来,滚动不会重置。
PS:请不要介意我只是想看看有什么效果的样式决定。
答案 1 :(得分:0)
首先,您需要在App组件外部映射路线。然后,您可以在示例 {routeComponents}
中将它们映射的路由添加到应用程序中const routeComponents = routes.map(({ path, component }, key) => <Route exact path={path} component={component} key={key} />);
const App = () => (<BrowserRouter><div>{routeComponents}</div></BrowserRouter>);
在validation.js中,您在 {items.map ...} 行中也有警告。我在链接中添加了 key 道具,错误消失了
{items.map((item, index) => (
<Link to={`/validations/${index}`} key={index}>
Item {index}
</Link>
))}