Maison  >  Questions et réponses  >  le corps du texte

Résoudre davantage de problèmes de crochet : un guide simple

<p>Je rencontre des problèmes avec les hooks dans mon projet. Il s'agit d'une fonction qui vérifie les autorisations des utilisateurs et renvoie vrai ou faux.</p> <pre class="brush:php;toolbar:false;">import { useSelector } depuis "react-redux" ; const CheckPermission = (module_key, permission_key) => { const { utilisateur } = useSelector((state) => ({ utilisateur : state.auth.user, })); const rolePermissions = utilisateur?.role?.role_permissions ?? [] ; const return_value = !!rolePermissions.find( (p_list) => p_list.module?.key === module_key && p_list.permission?.key === permission_key ); retourner return_value ; } ; exporter CheckPermission par défaut;</pre> <p>我在我的侧边栏组件中使用它</p> <pre class="brush:php;toolbar:false;">const renderMenu = (menu, touche) => { if (!CheckPermission(menu.moduleKey, menu.permissionKey)) { renvoie null ; } retour ( <Tooltip title={menu.name} placement="right" key={key}> <NavLink activeClassName={styles.active} exact className={styles.item} à={menu.chemin} > <span className={styles.iconBox}>{menu.icon}</span> <span className={styles.itemText}> {menu.name}</span> </NavLink> </Info-bulle> ); } ; export par défaut ({effondrement, onCollapse, isAdmin }) => { const { utilisateur } = useSelector((state) => ({ utilisateur : state.auth.user, })); retour ( <Layout.Sider thème = "lumière" className={classnames(styles.sider, cliff ? styles.collapsed : "")} pliant effondré={collapse} onCollapse={onCollapse} width={collapse ? 64 : 264} onBreakpoint={() => {}} point d'arrêt="xl" style={{ débordement : "auto", hauteur : "100vh", position : "fixe", gauche : 0, haut : 0, paddingTop : "50px", }} > <div className={styles.action}> {utilisateur && utilisateur.read_only ? menus.map((menu, i) => { if (menu.name === "Харилцагч") { return renderMenu(menu, je); } autre { retour ( menu && menu.enfants && // eslint-disable-tableau-rappel-retour de la ligne suivante menu.children.map((sous-menu, j) => { if (submenu.name === "QR dans") { retour ( <div key={i} className={styles.parentnav}> {renderMenu(sous-menu, j)} </div> ); } }) ); } }) : menus.map((menu, i) => { si (menu.chemin) { return renderMenu(menu, je); } autre { retour ( <div key={i} className={styles.parentnav}> {menu.nom ? ( <div className={`${styles.navlabel} ${styles.partentText}`} > {menu.nom} </div> ) : nul} {menu.children.map((sous-menu, j) => { if (!submenu.path) renvoie null ; si (estAdmin) { return renderMenu (sous-menu, j); } autre { renvoie null ; } })} </div> ); } })} </div> </Layout.Sider> ); };</pré> <p>但是它抛出了"Erreur : rendu plus de crochets que lors du rendu précédent." <p>
P粉883278265P粉883278265454 Il y a quelques jours409

répondre à tous(1)je répondrai

  • P粉824889650

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

    "Erreur : rendu avec plus de hooks que le dernier rendu" se produit généralement lorsque vous utilisez des hooks React (tels que useSelector) d'une manière qui enfreint les règles des hooks. Les règles stipulent que les hooks doivent toujours être appelés au niveau supérieur d'un composant fonctionnel, et non dans des boucles, des conditions ou des fonctions imbriquées. Dans votre code, vous semblez utiliser la fonction CheckPermission en boucle et conditionnellement.

    // 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;

    répondre
    0
  • Annulerrépondre