脚把脚带你撸一个简易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了。希望大家看了这篇文章也能动手敲敲,有问题可以评论区讨论哈~~

相关推荐
XinZong16 分钟前
【VSCode插件推荐】想准时下班,你需要codemoss的帮助,分享AI写代码的愉快体验,附详细安装教程
前端·程序员
ErvinHowell23 分钟前
文件MD5生成性能大提升!如何实现分片与Worker优化
前端·vue.js·算法
想做白天梦39 分钟前
LeetCode :150. 逆波兰表达式求值(含求后缀表达式和中缀转后缀表达式)
java·前端·算法
迃-幵44 分钟前
力扣:225 用队列实现栈
android·javascript·leetcode
s甜甜的学习之旅2 小时前
前端js处理list(数组)
开发语言·前端·javascript
小布布的不2 小时前
MyBatis 返回 Map 或 List<Map>时,时间类型数据,默认为LocalDateTime,响应给前端默认含有‘T‘字符
前端·mybatis·springboot
aPurpleBerry2 小时前
Vue3+axios+Vite配置Proxy代理解决跨域
前端·javascript·vue.js
星月前端2 小时前
【vue-pdf】简单封装pdf预览组件
javascript·vue.js·pdf
JustCouvrir2 小时前
macOS|前端工程部署到Nginx服务器
服务器·前端·nginx
代码哈士奇2 小时前
mqtt 传递和推送 温湿度计消息 js
开发语言·前端·javascript·硬件·esp8266