我正在使用react (Hooks),并且我已经做了很多事情,但是在这里我已经被困在一个地方几天了。
我想创建一个scrollspy使用react that too with routing,当滚动新菜单激活时,我想改变路由[请参考此链接][1]这就是我想要实现的,这里他们使用哈希路由.
我在做什么
- 我有一个侧边栏,里面有一些菜单。
- 我正在循环数据并显示侧边栏,它工作良好。
我想要实现的
- 对于每个菜单我都有一些数据,我想显示
- 所以当我滚动第一个菜单文本结束时,我想激活下一个菜单,但也要改变路由
- 有一些路由是——/home,/profile,/status,/info。
- 所以当我**scrollspy **改变菜单时,我也想改变路由,因为我有Api的数据。
- 我无法显示特定路由中的数据,例如当我单击配置文件时,我想在该页面中显示该数据,但不能传递该数据。
用简单的点击路由很好,我能很容易地实现它,但在这里我想实现别的东西,面临着困难的时间去做。
<<p>JSON数据/strong>[
{
menu: "HOME",
path: "home",
data:
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."
},
{
menu: "PROFILE",
path: "profile",
data:
"The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from 'de Finibus Bonorum et Malorum' by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham."
},
{
menu: "STATUS",
path: "status",
data:
"It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English."
},
{
menu: "INFO",
path: "info",
data:
"Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like). q"
}
]
在上面的数据中,我有数据我想在每个路由中显示,滚动或点击。
在点击我已经能够改变路由和渲染点击页面。
我的代码
下面是我的菜单栏。js文件
<div className="menuBar">
<Nav className="mr-auto ml-1">
{data.map((li, ind) => (
<li className="nav-item" key={li.path}>
<NavLink
className="nav-link"
activeClassName="active"
to={`${li.path}`}
onClick={() => OnclickSidebar(li.menu, li.path)}
>
{li.menu}
</NavLink>
</li>
))}
</Nav>
</div>
route.js文件
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/home" component={Home} />
<Route path="/profile" component={Profile} />
<Route path="/status" component={Status} />
<Route path="/info" component={Info} />
<Route path="/*" component={() => "Page not found"} />
</Switch>
以上就是我到目前为止所取得的成就,现在我没有任何前进的想法,所以在这里寻找一些想法。
PS:请参考[This is what I exactly I want][1],这里已经使用了哈希路由。
编辑/更新
我有上面的数据,我已经分享了我想要实现的链接,我愿意就如何接近这个问题提出建议。因为我在这方面是全新的,不知道我应该如何开始实现这个目标。
分享更多信息
当我打开页面时,初始路由显示[![检查这张图,它显示了公共路线][2]][2]
现在,当我在侧边栏上滚动时,总览变成活动的,总览路由显示[!][查看图片][3][3]
所以上面我想达到。
同样它适用于所有的边栏菜单,现在边栏也有一些子菜单,它的工作方式完全相同,如果我能够实现一个流这个子菜单,我可以自己做。我只是需要一个好的开始。
[My code sandbox link][4]
如何检查子菜单并在菜单处于活动状态时打开
实际上我的数据有一些子菜单
[
{
menu: 'HOME',
path: 'home',
data:
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
},
{
menu: 'PROFILE',
path: 'profile',
data:
"The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from 'de Finibus Bonorum et Malorum' by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.",
Sub_menu: [ // some menus have submenus also
{
menu: 'Profile1',
path: '/profile/profile1',
data: 'Some data for the sub menu',
},
{
menu: 'Profile2',
path: '/profile/profile2',
data: 'Some data for the sub menu 2',
},
],
},
{
menu: 'STATUS',
path: 'status',
data:
"It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
},
{
menu: 'INFO',
path: 'info',
data:
"Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like). q",
Sub_menu: [
{
menu: 'info1',
path: '/info/info1',
data: 'Some data for the sub menu info',
},
{
menu: 'info2',
path: '/info/info2',
data: 'Some data for the sub menu info2',
},
],
},
];
[![5]][5]
[![6] [6]
这个实现有三个方面:
- 导航条 路由器
- scrollspy
在NavBar
:这里需要一个第三方库,让我们安装它:
npm install react-router-hash-link
现在,实现它:
import {HashLink} from 'react-router-hash-link';
const NavBar = () => (
<div className="menuBar">
<div className="mr-auto ml-1">
{data.map((item) => (
<li className="nav-item" key={item.path}>
<HashLink to={`#${item.path}`} smooth={true}>
{item.menu}
</HashLink>
</li>
))}
</div>
</div>
);
此时,NavBar
组件完成。让我们继续第二部分,Router
您需要一个组件来呈现其中的所有数据:
<Route exact={true} path="/" component={Home} />
在示例Home
组件中,我们需要一个组件来呈现每个部分:
const Section = ({ title, description, path }) => {
const history = useHistory();
useEffect(() => {
const el = document.getElementById(path);
const observer = new window.IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
history.push(`#${path}`);
return;
}
},
{
root: null,
threshold: 0.1 // set offset 0.1 means trigger if atleast 10% of element in viewport
}
);
observer.observe(el);
}, [path, history]);
return (
<div style={{ height: "500px" }}>
<h3 id={path}>{title}</h3>
<p>{description}</p>
</div>
);
};
最重要的魔法在这里,在useEffect
钩子中,当前活动的部分已被监视。让我们一起使用NavBar
和Section
组件:
const App = () => {
return (
<div>
<div>
<NavBar />
</div>
<div>
{data.map((item) => (
<Section
title={item.menu}
description={item.data}
path={item.path}
key={item.path}
/>
))}
</div>
</div>
);
};
export default App;
你也可以在codesandbox上查看简单版本。