脚把脚带你撸一个简易react后台...........

看了很多遍react文档,同时也跟着文档写了好几次demo,心里觉得什么hooks也不过如此嘛,但总觉得不得劲,跟真实项目比,那些demo有点食之无味... 不知道有多少老哥跟我一样的心理->-<-。

这不趁着休息,(好吧是失业了。。。)想着这次一定要把react给拿下,于是有了这篇文章,首先声明,本人纯第一次写react,代码写的不好望大佬们海涵,本文旨在提供一个教程(如果可以称之为教程的话hhh)给没接触过react,或者是看过react文档却没有实战的同学。话不多说,正文开始。

介绍

本次项目是基于react18 + react-router-dom6 + antd5完成,布局是左右结构,左侧菜单完成了展开收缩、多层级嵌套展示、刷新记录展开菜单项等功能,右侧分为上下两部分,上部分为面包屑导航和个人信息展示,面包屑跟随路由变化,下面部分为内容区域,随点击菜单进行页面变化。具体如下Gif所示

准备

本次项目是直接通过create-react-app的方式创建,我把拉包的代码放一下,其他就不赘述了

js 复制代码
npx create-react-app my-app
cd my-app
npm install --save react-router-dom
npm install antd --save
npm i

ok 其实也可以一次拉三个包,也可以用yarn,看你们自己就行。

开始撸

这个时候运行肯定大家都很熟悉啦

咱们把一些默认内容都删删,然后引入下antd组件看能否正常展示,可以的话就可以开始撸布局,路由啥的先不管。按各位喜欢的样子做就行,目前我是创建了一个layout文件放布局文件,具体的文件和页面如下所示:

antd组件的使用我就不赘述了,布局大致长这样,现在是全静态的。我们先来实现菜单栏的展开和收缩。其实就是一个变量的true/falseq切换而已,代码如下

js 复制代码
 const [collapsed, setCollapsed] = useState(false);
 const toggleCollapsed = () => {
    setCollapsed(!collapsed);
  };
 
 //在menu上有个属性inlineCollapsed 
  <Menu mode="inline" theme="dark" inlineCollapsed={collapsed} items={menuData} />
  
 //接着在展开/收缩的icon上添加事件
 <Button type="primary" shape="circle" onClick={toggleCollapsed}> {collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />} </Button>

此时,展开收缩完成。接下来就是进行点击菜单进行路由的切换了。我们引入react-router-dom,很多小的demo教程都是直接在文件里写路由,我们这是正式项目来的嘛,就直接抽出来哈,创建router文件,通过createBrowserRouter创建路由实例,然后你可以添加一些页面来跟路由进行匹配,这个时候我在官网看到的例子是这样的:

我此时心里想的是还挺方便,把<RouterProvider router={router} />放到content那就完事了,事实上也确实是可以正常渲染的。此时的文件夹和页面如图所示:

一切都很完美是不是,接下来开始来做菜单点击事件。注意,坑要来了!!!!!

找到menu组件,添加onClick事件,然后通过router的文档找到跳转方法useNavigate,如下

js 复制代码
import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
 const handleMenuOnClick = (e) => {
    const path = e.keyPath.reverse();
    navigate(`/${path.join('/')}`);
  };


  <Menu mode="inline" theme="dark" inlineCollapsed={collapsed} items={menuData} onClick={handleMenuOnClick} />

写完之后一看,代码没报错,nice,然后切换到浏览器,wc怎么一片红,no

可以看到,错误是说 useNavigate() 这个方法必须在Router包裹的组件中才能使用,我了个去,朋友们注意到了嘛,我们刚刚把RouterProvider写在了content里,而现在是在slider侧边菜单使用useNavigate,所以才导致的报错,为此我还发沸点问了掘金的大佬们,然后知道了如何修改,具体可以看xdm,初次尝试react,现在有这么个布局,希望在点击左侧菜单时对应展示右侧内...#掘金沸点# juejin.cn/pin/7327487...

好那咱们开始修改一下,首先把RouterProvider放到index.js中,

js 复制代码
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
  );
  
  //替换成
  const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

可以看到APP.js文件已经不需要了,然后页面也变成了这样 现在就能确保route在顶层,接下来你在项目哪里使用router的api都不会出问题了,但是还有一个问题就是布局全没了,没事,经过搜索我了解到,有一个Outlet组件类似vue-outer的router-view,但功能不完全一样,我们可以把页面的左右布局当作根布局,然后把菜单对应的页面当作子路由,由Outlet展示即可,然后我们把APP.js中的内容移到layout文件夹中用一个新文件放置,然后把路由改造一下,具体如图:

终于恢复原样啦。还记得我们刚写的菜单点击事件嘛,试试吧,成功的感觉如此美妙!!!

但还没完,此时你会发现刷新页面后,菜单选中消失了,所以需要优化,这个时候需要用到useEffect,我们希望在页面初始化的时候通过路由来展开某项菜单,react-router提供了useLocation来获取路径信息,meun提供了这几个api可以做到设置菜单

代码如下

js 复制代码
  const navigate = useNavigate();
  const location = useLocation();
 useEffect(() => {
    const { pathname } = location;
    const pathArr = pathname.split('/');
    setOpenKeys(pathArr);
    setSelectKeys(pathArr.pop());
  }, [location]);

  const onOpenChange = (openKeys) => {
    // console.log(openKeys);
    setOpenKeys(openKeys);
  };

  const handleMenuOnClick = (e) => {
    // console.log(e);
    setSelectKeys(e.key);
    const path = e.keyPath.reverse();
    navigate(`/${path.join('/')}`);
  };
 <Menu mode="inline" theme="dark" inlineCollapsed={collapsed} items={menuData} openKeys={openKeys} selectedKeys={selectKeys} onClick={handleMenuOnClick} onOpenChange={onOpenChange} />

到这里,就可以进行点击切换菜单对应页面,以及刷新回显菜单栏的功能了,最后的面包屑回显和展示也是基于location来实现。

end

通过这次的练习,我也更加熟悉了react以及相关生态的使用,可能你们会说这so easy,但没关系,我确实学到了一些,也不惧怕react了。希望大家看了这篇文章也能动手敲敲,有问题可以评论区讨论哈~~

相关推荐
zhougl99611 分钟前
html处理Base文件流
linux·前端·html
花花鱼15 分钟前
node-modules-inspector 可视化node_modules
前端·javascript·vue.js
HBR666_18 分钟前
marked库(高效将 Markdown 转换为 HTML 的利器)
前端·markdown
careybobo2 小时前
海康摄像头通过Web插件进行预览播放和控制
前端
TDengine (老段)2 小时前
TDengine 中的关联查询
大数据·javascript·网络·物联网·时序数据库·tdengine·iotdb
杉之3 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
喝拿铁写前端3 小时前
字段聚类,到底有什么用?——从系统混乱到结构认知的第一步
前端
再学一点就睡3 小时前
大文件上传之切片上传以及开发全流程之前端篇
前端·javascript
木木黄木木4 小时前
html5炫酷图片悬停效果实现详解
前端·html·html5
请来次降维打击!!!5 小时前
优选算法系列(5.位运算)
java·前端·c++·算法