javascript - React Router v4 - 切换组件时保持滚动位置
问题描述
我有两个<Route>
用 react-router 创建的。
- /cards -> 纸牌游戏列表
- /cards/1 -> 纸牌游戏 #1 的详细信息
当用户单击“返回列表”时,我想滚动用户在列表中的位置。
我怎样才能做到这一点?
解决方案
代码沙箱的工作示例
React Router v4 不提供对滚动恢复的开箱即用支持,而且目前也不支持。在React Router V4 - Scroll Restoration of their docs 部分中,您可以阅读有关它的更多信息。
因此,每个开发人员都需要编写逻辑来支持这一点,尽管我们确实有一些工具可以实现这一点。
element.scrollIntoView()
.scrollIntoView()
可以在一个元素上调用,你可以猜到,它会将它滚动到视图中。支持相当不错,目前97%的浏览器都支持。资料来源:icanuse
组件<Link />
可以传递状态
React Router 的 Link 组件有一个to
prop,你可以提供一个对象而不是字符串。这就是他的样子。
<Link to={{ pathname: '/card', state: 9 }}>Card nine</Link>
我们可以使用状态将信息传递给将要渲染的组件。在这个例子中,state 被分配了一个数字,它足以回答你的问题,你稍后会看到,但它可以是任何东西。路由/card
渲染<Card />
现在可以访问props.location.state中的变量 state ,我们可以随意使用它。
标记每个列表项
在渲染各种卡片时,我们为每张卡片添加一个独特的类。这样我们就有了一个可以传递的标识符,并且当我们导航回卡片列表概览时,我们知道该项目需要滚动到视图中。
解决方案
<Cards />
呈现一个列表,每个项目都有一个唯一的类;- 单击项目时,
Link />
将唯一标识符传递给<Card />
; <Card />
使用唯一标识符呈现卡片详细信息和后退按钮;<Cards />
单击并安装该按钮后,.scrollIntoView()
将滚动到使用来自 的数据之前单击过的项目props.location.state
。
以下是各个部分的一些代码片段。
// Cards component displaying the list of available cards.
// Link's to prop is passed an object where state is set to the unique id.
class Cards extends React.Component {
componentDidMount() {
const item = document.querySelector(
".restore-" + this.props.location.state
);
if (item) {
item.scrollIntoView();
}
}
render() {
const cardKeys = Object.keys(cardData);
return (
<ul className="scroll-list">
{cardKeys.map(id => {
return (
<Link
to={{ pathname: `/cards/${id}`, state: id }}
className={`card-wrapper restore-${id}`}
>
{cardData[id].name}
</Link>
);
})}
</ul>
);
}
}
// Card compoment. Link compoment passes state back to cards compoment
const Card = props => {
const { id } = props.match.params;
return (
<div className="card-details">
<h2>{cardData[id].name}</h2>
<img alt={cardData[id].name} src={cardData[id].image} />
<p>
{cardData[id].description} <a href={cardData[id].url}>More...</a>
</p>
<Link
to={{
pathname: "/cards",
state: props.location.state
}}
>
<button>Return to list</button>
</Link>
</div>
);
};
// App router compoment.
function App() {
return (
<div className="App">
<Router>
<div>
<Route exact path="/cards" component={Cards} />
<Route path="/cards/:id" component={Card} />
</div>
</Router>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
推荐阅读
- truffle - 类型错误:contracts_build_directory 不是函数
- css - textDecoration:直通在 React Native 样式的组件中不起作用
- pipe - 在 iex 的下一行使用管道(之前的语法错误:'|>')
- javascript - 谁能告诉我代码中发生了什么?
- r - R中有没有办法在ifelse中使用前一行值(正在创建)
- javascript - 如何将移动的 div 限制在包含的 div 内?
- machine-learning - 如何使用 SpaCy Matcher 更快地找到匹配项?
- arrays - 在 Julia 中收集数组的元素
- angular - How to pass component name as argument and receive it in function
- elasticsearch - 带条件的 Elasticsearch 基数聚合