解決更多的鉤子問題:簡易指南
P粉883278265
P粉883278265 2023-08-14 13:19:01
0
1
415
<p>我在我的專案中遇到了一些鉤子問題。這是一個用於檢查使用者權限並傳回true或false的函數。</p> <pre class="brush:php;toolbar:false;">從「react-redux」匯入 { useSelector }; const CheckPermission = (module_key,permission_key) =>; { const { 使用者 } = useSelector((狀態) => ({ 使用者:state.auth.user, })); const rolePermissions = user?.role?.role_permissions ?? []; const return_value = !!rolePermissions.find( (p_list) =>; p_list.module?.key === module_key && p_list.permission?.key ===permission_key ); 返回返回值; }; 導出預設CheckPermission;</pre> <p>然後我在我的側邊欄組件中使用它</p>
const renderMenu = (選單, 鍵) =>; {
  if (!CheckPermission(menu.moduleKey, menu.permissionKey)) {
    返回空值;
  }

  返回 (
    <工具提示標題={menu.name}placement=“right”key={key}>
      <導航連結
        activeClassName={styles.active}
        精確的
        類別名稱={styles.item}
        到={選單.路徑}
      >
        {menu.icon};
        <span className={styles.itemText}> {選單.名稱}</span>
      </NavLink>
    </工具提示>
  );
};

導出預設值({collapse,onCollapse,isAdmin})=> {
  const { 使用者 } = useSelector((狀態) => ({
    使用者:state.auth.user,
  }));

  返回 (
    <佈局.Sider
      主題=“光”
      className = {classnames(styles.sider,折疊?styles.collapsed:"")}
      可折疊的
      折疊={折疊}
      onCollapse={onCollapse}
      寬度={折疊? 64:264}
      onBreakpoint={() =>; {}}
      斷點=“xl”
      風格={{
        溢出:“自動”,
        高度:“100vh”,
        位置:“固定”,
        左:0,
        頂部:0,
        頂部填充:“50px”,
      }}
    >
      
; {用戶&&使用者唯讀 ?選單.map((選單, i) => { if (menu.name === "Харилцагч") { 返回渲染選單(選單,i); } 別的 { 返回 ( 菜單&& 菜單.children && // eslint-disable-next-line array-callback-return menu.children.map((子選單, j) => { if (submenu.name === "QR данс") { 返回 ( <div key={i} className={styles.parentnav}> {渲染選單(子選單,j)}
; ); } }) ); } }) : 選單.map((選單, i) => { if (選單.路徑) { 返回渲染選單(選單,i); } 別的 { 返回 ( <div key={i} className={styles.parentnav}> {菜單.名稱? (
{菜單.名稱}
) : 無效的} {menu.children.map((子選單, j) => { if (!submenu.path) 回傳 null; 如果(是管理員){ 返回渲染選單(子選單,j); } 別的 { 返回空值; } })}
); } })}
</Layout.Sider> ); };</pre> <p>但它拋出了“錯誤:比之前的渲染期間渲染了更多的鉤子。”,我知道在其他地方正確使用我的 checkPermission 函數。</p> <p> 我嘗試在循環中使用 checkPermission 函數,結果是一樣的。</p>
1
0
0
P粉883278265
P粉883278265

全部回覆(1)
P粉824889650

"錯誤:渲染時使用的hooks數量多於上一次渲染時的數量",通常發生在您使用React hooks(例如useSelector)的方式違反了hooks規則時。規則規定,hooks必須始終在函數元件的頂層調用,而不是在循環、條件或巢狀函數中調用。在您的程式碼中,您似乎在循環和條件中使用了CheckPermission函數。

// Sidebar.js
import React from "react";
import { useSelector } from "react-redux";
import { NavLink, Tooltip } from "your-react-ui-library"; // 导入您的UI库
const Sidebar = ({ collapse, onCollapse, isAdmin, menus }) => {
  const { user } = useSelector((state) => ({
    user: state.auth.user,
  }));

  // 将权限检查逻辑直接移入Sidebar组件
  const checkPermission = (module_key, permission_key) => {
    const rolePermissions = user?.role?.role_permissions ?? [];
    return !!rolePermissions.find(
      (p_list) =>
        p_list.module?.key === module_key &&
        p_list.permission?.key === permission_key
    );
  };

  const renderMenu = (menu, key) => {
    // 使用本地的checkPermission函数进行权限检查
    if (
      !checkPermission(menu.moduleKey, menu.permissionKey) ||
      (!isAdmin && !menu.path)
    ) {
      return null;
    }

    return (
      <Tooltip title={menu.name} placement="right" key={key}>
        <NavLink
          activeClassName={styles.active}
          exact
          className={styles.item}
          to={menu.path}
        >
          <span className={styles.iconBox}>{menu.icon}</span>
          <span className={styles.itemText}> {menu.name}</span>
        </NavLink>
      </Tooltip>
    );
  };

  return (
    <Layout.Sider
      // ... 其他属性和样式 ...
    >
      <div className={styles.action}>
        {user && user.read_only
          ? menus.map((menu, i) => {
              if (menu.name === "Харилцагч") {
                return renderMenu(menu, i);
              } else {
                return (
                  menu &&
                  menu.children &&
                  // eslint-disable-next-line array-callback-return
                  menu.children.map((submenu, j) => {
                    if (submenu.name === "QR данс") {
                      return (
                        <div key={i} className={styles.parentnav}>
                          {renderMenu(submenu, j)}
                        </div>
                      );
                    }
                  })
                );
              }
            })
          : menus.map((menu, i) => {
              if (menu.path) {
                return renderMenu(menu, i);
              } else {
                return (
                  <div key={i} className={styles.parentnav}>
                    {menu.name ? (
                      <div
                        className={`${styles.navlabel} ${styles.partentText}`}
                      >
                        {menu.name}
                      </div>
                    ) : null}
                    {menu.children.map((submenu, j) => {
                      if (!submenu.path) return null;

                      if (isAdmin) {
                        return renderMenu(submenu, j);
                      } else {
                        return null;
                      }
                    })}
                  </div>
                );
              }
            })}
      </div>
    </Layout.Sider>
  );
};

export default Sidebar;
熱門專題
更多>
熱門文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板