[React log] Primer contacto con react-hooks

Prefacio

Ahora, los sitios un poco más grandes usarán paralelo H5 / PC, a través de nignx para obtener la información de UA del navegador para cambiar de sitio.

Pero esto es difícil de lograr para algunos sitios corporativos o pequeños proyectos con personal insuficiente.

Realizar un diseño receptivo a través de consultas de medios CSS es la forma principal.

Sin embargo, a veces en un programa React, es necesario renderizar condicionalmente diferentes componentes según el tamaño de la pantalla (escribir consultas de medios es demasiado problemático, es mejor escribir otro componente), de hecho, usar React Hooks puede ser más flexible de lograr .

1. Opción 1: innerWidth

Una solución muy simple y aproximada, que es conocida por todos los front-end:

const MyComponent = () => {
    
    
  // 当前窗口宽度
  const width = window.innerWidth;
  // 邻介值
  const breakpoint = 620;
  // 宽度小于620时渲染手机组件,反之桌面组件
  return width < breakpoint ? <MobileComponent /> : <DesktopComponent />;
}

Esta sencilla solución definitivamente funcionará. Según el ancho de la ventana del dispositivo del usuario, podemos presentar una vista de escritorio o una vista móvil.

Sin embargo, cuando se cambia el tamaño de la ventana, la actualización del valor de ancho no se resuelve y se puede representar el componente incorrecto.

2. Opción 2: Ganchos + cambio de tamaño

También es sencillo decir que cuando se supervisa el evento de cambio de tamaño, se activa useEffect para cambiar los datos.

const MyComponent = () => {
    
    
  const [width, setWidth] = React.useState(window.innerWidth);
  const breakpoint = 620;

  React.useEffect(() => {
    
    
    window.addEventListener("resize", () => setWidth(window.innerWidth));
  }, []);

  return width < breakpoint ? <MobileComponent /> : <DesktopComponent />;
}

Pero usted, que es experto en Hooks, debe saber que aquí hay un problema de consumo de rendimiento de memoria: ¡el evento de cambio de tamaño no se ha eliminado!

Versión optimizada:

const useViewport = () => {
    
    
  const [width, setWidth] = React.useState(window.innerWidth);

  React.useEffect(() => {
    
    
    const handleWindowResize = () => setWidth(window.innerWidth);
    window.addEventListener("resize", handleWindowResize);
    return () => window.removeEventListener("resize", handleWindowResize);
  }, []);

  return {
    
     width };
}

3. Opción 3: crear useViewport

Los React Hooks personalizados pueden reutilizar componentes / funciones en la mayor medida posible. Construir uno también es muy simple:

const useViewport = () => {
    
    
  const [width, setWidth] = React.useState(window.innerWidth);

  React.useEffect(() => {
    
    
    const handleWindowResize = () => setWidth(window.innerWidth);
    window.addEventListener("resize", handleWindowResize);
    return () => window.removeEventListener("resize", handleWindowResize);
  }, []);

  return {
    
     width };
}

Código de componente simplificado:

const MyComponent = () => {
    
    
  const {
    
     width } = useViewport();
  const breakpoint = 620;

  return width < breakpoint ? <MobileComponent /> : <DesktopComponent />;
}

Pero hay otro problema de rendimiento aquí:

El diseño receptivo afecta a varios componentes. Si useViewport se utiliza en varios lugares, perderá rendimiento.

En este momento, necesita otro hijo de React: React Context (Context) para ayudar.

4. La solución definitiva: Hooks + Context

Crearemos un nuevo archivo viewportContext en el que se puede almacenar el estado del tamaño actual de la ventana gráfica y la lógica de cálculo.

const viewportContext = React.createContext({
    
    });

const ViewportProvider = ({
    
     children }) => {
    
    
  // 顺带监听下高度,备用
  const [width, setWidth] = React.useState(window.innerWidth);
  const [height, setHeight] = React.useState(window.innerHeight);

  const handleWindowResize = () => {
    
    
    setWidth(window.innerWidth);
    setHeight(window.innerHeight);
  }

  React.useEffect(() => {
    
    
    window.addEventListener("resize", handleWindowResize);
    return () => window.removeEventListener("resize", handleWindowResize);
  }, []);

  return (
    <viewportContext.Provider value={
    
    {
    
     width, height }}>
      {
    
    children}
    </viewportContext.Provider>
  );
};

const useViewport = () => {
    
    
  const {
    
     width, height } = React.useContext(viewportContext);
  return {
    
     width, height };
}

A continuación, debe estar en el nodo raíz de React para asegurarse de que la aplicación se haya empaquetado:

const App = () => {
    
    
  return (
    <ViewportProvider>
      <AppComponent />
    </ViewportProvider>
  );
}

En el futuro, cada useViewport () en realidad solo compartirá Hooks.

const MyComponent = () => {
    
    
  const {
    
     width } = useViewport();
  const breakpoint = 620;

  return width < breakpoint ? <MobileComponent /> : <DesktopComponent />;
}

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/u013034585/article/details/106327634
Recomendado
Clasificación