DEV Community

Cover image for MaterialUI. El componente App Bar y la propiedad position="fixed"
Mauricio
Mauricio

Posted on

MaterialUI. El componente App Bar y la propiedad position="fixed"

En mi proyecto de React, he utilizado el componente App Bar de MaterialUI como barra de navegación. Al emplear position="fixed", el App Bar se mantiene visible en la parte superior de la ventana del navegador, mientras el usuario explora el sitio web.

Ésta propiedad tiene un pequeño detalle, la dimensión del elemento App Bar no afecta al resto de la página. Esto puede causar que alguna parte del contenido sea invisible detrás de la barra de aplicaciones.

Una solución rápida es colocar cualquier elemento, como por ejemplo un "div", que se renderice con la propiedad "height" equivalente a la altura de la App Bar para cubrir éste espacio, es una salida sencilla.

La documentación de MaterialUI brinda tres posibles soluciones también:

https://mui.com/material-ui/react-app-bar/#fixed-placement

Pero ninguna de éstas soluciones contempla que la App Bar cambie de tamaño, como puede ocurrir en el caso de un diseño responsivo, en donde los elementos se pueden reagrupar dependiendo del espacio disponible.

diferencias

Propiedad "heigh" dinámica

La solución que desarrollo aquí se lleva a cabo utilizando "Redux" pero se podría hacer utilizando las Props de los componentes.

Componente SpaceFixedNavbar.jsx

Creo un componente llamado "SpaceFixedNavbar", será el componente que tomará la propiedad "height" que tenga la App Bar.

import React, { useEffect } from "react";
import { useSelector } from "react-redux";

export const SpaceFixedNavbar = () => {
    const navbarHeight = useSelector((state) => state.heightNavBar);

    // useEffect(() => {
    //  console.log(navbarHeight);
    // }, [navbarHeight]);

    return (
        <div
            style={{
                display: "block",
                width: "100%",
                height: navbarHeight || "56px" ,
                backgroundColor: "#E53170",
            }}></div>
    );
};
Enter fullscreen mode Exit fullscreen mode
Componente App.jsx

Importo el componente "SpaceFixedNavbar" en el componente App.jsx; que se encargará de renderizarlo en cada componente en donde también se renderice la "NavBar"

function App() {
return (
    <>
    <BrowserRouter>
      <SpaceFixedNavbar/>
      <NavBar/>
        <Routes>
          <Route exact path="/" element={<Home/>} />
          <Route path="/AboutUs" element={<AboutUs/>} />
          <Route exact path="/Login" element={<Login/>} />
Enter fullscreen mode Exit fullscreen mode
Componente NavBar.jsx

En éste componente se utiliza "ResizeObserver" para monitorear el tamaño de la App Bar

export default function NavBar() {
    const dispatch = useDispatch();

    const componentRef = useRef(null);

    useEffect(() => {
        handleNavbarHeight(componentRef, dispatch);
    }, []);

    return (
        <AppBar
            position="fixed"
            ref={componentRef}
        >
            {...}
        </AppBar>
    );
}


const handleNavbarHeight = (componentRef, dispatch) => {
    const resizeObserver = new ResizeObserver(entries => {
        if (entries[0]?.target) {
        const newHeight = entries[0].target.offsetHeight;
        // console.log("Nuevo valor de altura:", newHeight);
        dispatch(setHeight(newHeight));
        }
    });

    if (componentRef.current)
        { resizeObserver.observe(componentRef.current); }

    return () => { resizeObserver.disconnect(); };
};
Enter fullscreen mode Exit fullscreen mode
Componente heightNavBar.js

Éste es el archivo "action" de Redux.

export const SET_HEIGHT = 'SET_HEIGHT';

export const setHeight = (height) => ({
    type: SET_HEIGHT,
    payload: height,
  });
Enter fullscreen mode Exit fullscreen mode
Componente RootReducer.js
const initialState = {
    {...}
    heightNavBar: 0,
};

const rootReducer = (state = initialState, action) => {
    switch (action.type) {
        {...}

        case SET_HEIGHT:
            return {
                ...state,
                heightNavBar: action.payload,
            };

        default:
            return { ...state };
    }
};

export default rootReducer;
Enter fullscreen mode Exit fullscreen mode

Finalizado

Finalmente se puede ver que el componente renderizado adapta su altura de acuerdo a la altura que tiene la NavBar.

Finalizado

Ahora que lo he terminado, creo que quedó algo largo para la pequeña funcionalidad que desempeña. Siéntete libre para proponer una solución alternativa más corta en los comentarios. Saludos!

Top comments (0)