Heim  >  Fragen und Antworten  >  Hauptteil

Lösen Sie weitere Hook-Probleme: Eine einfache Anleitung

<p>Ich habe einige Probleme mit Hooks in meinem Projekt. Dies ist eine Funktion, die Benutzerberechtigungen prüft und „true“ oder „false“ zurückgibt.</p> <pre class="brush:php;toolbar:false;">import { useSelector } from "react-redux"; const CheckPermission = (module_key,mission_key) => { const { user } = useSelector((state) => ({ Benutzer: 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 === Erlaubnisschlüssel ); return return_value; }; Standard-CheckPermission exportieren;</pre> <p>然后我在我的侧边栏组件中使用它</p> <pre class="brush:php;toolbar:false;">const renderMenu = (menu, key) => { if (!CheckPermission(menu.moduleKey, menu.permissionKey)) { null zurückgeben; } zurückkehren ( <Tooltip title={menu.name} Platzierung="right" key={key}> <NavLink activeClassName={styles.active} genau className={styles.item} to={menu.path} > <span className={styles.iconBox}>{menu.icon}</span> <span className={styles.itemText}> {menu.name}</span> </NavLink> </Tooltip> ); }; export default ({ collapse, onCollapse, isAdmin }) => { const { user } = useSelector((state) => ({ Benutzer: state.auth.user, })); zurückkehren ( <Layout.Sider Thema = „Licht“ className={classnames(styles.sider, Collaps? Styles.collapsed: "")} zusammenklappbar kollabiert={collapse} onCollapse={onCollapse} width={collapse ? 64: 264} onBreakpoint={() => {}} Haltepunkt="xl" Stil={{ Überlauf: „auto“, Höhe: „100vh“, Position: „fest“, links: 0, oben: 0, paddingTop: „50px“, }} > <div className={styles.action}> {Benutzer && user.read_only ? menus.map((menu, i) => { if (menu.name === "Харилцагч") { return renderMenu(menu, i); } anders { zurückkehren ( Menü && Menü.Kinder && // eslint-disable-next-line array-callback-return menu.children.map((submenu, j) => { if (submenu.name === "QR данс") { zurückkehren ( <div key={i} className={styles.parentnav}> {renderMenu(submenu, j)} </div> ); } }) ); } }) : menus.map((menu, i) => { if (menu.path) { return renderMenu(menu, i); } anders { zurückkehren ( <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); } anders { null zurückgeben; } })} </div> ); } })} </div> </Layout.Sider> ); };</pre> <p>但是它抛出了 „Fehler: Es wurden mehr Hooks gerendert als beim vorherigen Rendern.“ <p>
P粉883278265P粉883278265404 Tage vor362

Antworte allen(1)Ich werde antworten

  • P粉824889650

    P粉8248896502023-08-15 09:10:52

    "错误:渲染时使用的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;

    Antwort
    0
  • StornierenAntwort