返回

React系列:手把手教你搭建后台系统(Redux与路由鉴权)

前端

大家好,欢迎来到「React系列」的第二篇文章。在上一篇文章中,我们已经实现了侧边导航栏(Sidebar)的基本功能。现在,我们将继续完善Sidebar的功能,实现导航高亮和鉴权。

Redux 与数据管理

为了管理Sidebar的状态,我们将使用Redux。Redux是一个状态管理库,它可以帮助我们管理应用中的共享状态。

首先,我们需要安装Redux和React-Redux:

npm install redux react-redux

然后,我们创建一个Redux store来管理Sidebar的状态:

import { createStore } from 'redux';

const initialState = {
  sidebar: {
    menuItems: [
      {
        title: '首页',
        path: '/',
      },
      {
        title: '用户管理',
        path: '/users',
      },
      // 其他菜单项
    ],
    activeMenuItem: null,
  },
};

const store = createStore(reducer, initialState);

接下来,我们需要使用Redux的和connect()来使store可用:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import store from './store';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

实现导航高亮

为了实现导航高亮,我们需要在Sidebar中监听当前路由的变化。当路由发生变化时,我们需要更新Sidebar的activeMenuItem属性,以高亮当前激活的菜单项。

import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { setActiveMenuItem } from './actions';

const Sidebar = ({ menuItems, activeMenuItem, setActiveMenuItem }) => {
  const history = useHistory();

  useEffect(() => {
    const path = history.location.pathname;
    const activeMenuItem = menuItems.find(item => item.path === path);
    setActiveMenuItem(activeMenuItem);
  }, [history, menuItems, setActiveMenuItem]);

  return (
    <nav className="sidebar">
      <ul>
        {menuItems.map(item => (
          <li key={item.title} className={item === activeMenuItem ? 'active' : ''}>
            <Link to={item.path}>{item.title}</Link>
          </li>
        ))}
      </ul>
    </nav>
  );
};

const mapStateToProps = state => ({
  menuItems: state.sidebar.menuItems,
  activeMenuItem: state.sidebar.activeMenuItem,
});

const mapDispatchToProps = dispatch => ({
  setActiveMenuItem: activeMenuItem => dispatch(setActiveMenuItem(activeMenuItem)),
});

export default connect(mapStateToProps, mapDispatchToProps)(Sidebar);

实现鉴权

为了实现鉴权,我们需要在Sidebar中判断用户是否拥有访问某个菜单项的权限。如果用户没有权限,则该菜单项应被禁用。

import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { setActiveMenuItem } from './actions';

const Sidebar = ({ menuItems, activeMenuItem, setActiveMenuItem, isAuthenticated }) => {
  const history = useHistory();

  useEffect(() => {
    const path = history.location.pathname;
    const activeMenuItem = menuItems.find(item => item.path === path);
    setActiveMenuItem(activeMenuItem);
  }, [history, menuItems, setActiveMenuItem]);

  return (
    <nav className="sidebar">
      <ul>
        {menuItems.map(item => (
          <li key={item.title} className={item === activeMenuItem ? 'active' : ''}>
            {isAuthenticated ? (
              <Link to={item.path}>{item.title}</Link>
            ) : (
              <span>{item.title}</span>
            )}
          </li>
        ))}
      </ul>
    </nav>
  );
};

const mapStateToProps = state => ({
  menuItems: state.sidebar.menuItems,
  activeMenuItem: state.sidebar.activeMenuItem,
  isAuthenticated: state.auth.isAuthenticated,
});

const mapDispatchToProps = dispatch => ({
  setActiveMenuItem: activeMenuItem => dispatch(setActiveMenuItem(activeMenuItem)),
});

export default connect(mapStateToProps, mapDispatchToProps)(Sidebar);

好了,以上就是如何在React应用中使用Redux实现导航高亮和鉴权。希望这篇文章对大家有所帮助。