【问题标题】:Setting state without re-rendering with useEffect not working设置状态而不使用 useEffect 重新渲染不起作用
【发布时间】:2020-06-20 21:11:19
【问题描述】:

我只需要根据屏幕大小实时更改我的状态值。即使我的屏幕尺寸发生了变化,除非我重新加载页面,否则我的计数值保持不变。这需要实时更新以获得更好的响应式设计。这是我的代码。谢谢!

import React, { useState, useEffect } from 'react';
import Carousel from '@brainhubeu/react-carousel';
import '@brainhubeu/react-carousel/lib/style.css';
import { useMediaQuery } from 'react-responsive'

const MyCarousel = () => {

    useEffect(() => {
        loadMediaQuery();
    }, []);

    const [count, setCount] = useState(0);

    const loadMediaQuery = () =>{
        if (tablet)
            setCount(1)
        if (phone)
            setCount(2)
        if (desktop)
            setCount(3)
    }

    const tablet = useMediaQuery({
        query: '(max-width:  876px)'
    })
    const phone = useMediaQuery({
        query: '(max-width:  576px)'
    })
    const desktop = useMediaQuery({
        query: '(min-width:  876px)'
    })

    return (
        <div>
            <Carousel slidesPerPage={count} >
            <img className="image-one"/>
            <img className="image-two"/>
            <img className="image-three"/>
            </Carousel>
      </div>
    );
}

【问题讨论】:

    标签: reactjs state react-hooks setstate use-effect


    【解决方案1】:

    那是因为您的useEffect 没有依赖项,所以它仅在组件安装后加载一次。 要解决这个问题,您应该有以下代码:

    import React, { useState, useEffect } from 'react';
    import Carousel from '@brainhubeu/react-carousel';
    import '@brainhubeu/react-carousel/lib/style.css';
    import { useMediaQuery } from 'react-responsive';
    
    const MyCarousel = () => {
    
      const tablet = useMediaQuery({
        query: '(max-width:  876px)'
      });
    
      const phone = useMediaQuery({
        query: '(max-width:  576px)'
      });
    
      const desktop = useMediaQuery({
        query: '(min-width:  876px)'
      });
    
      useEffect(() => {
        loadMediaQuery();
      }, [tablet, phone, desktop]);
    
      const [count, setCount] = useState(0);
    
      const loadMediaQuery = () =>{
        if (tablet)
          setCount(1)
        else if (phone)
          setCount(2)
        else if (desktop)
          setCount(3)
        }
    
        return (
          <div>
            <Carousel slidesPerPage={count} >
              <img className="image-one"/>
              <img className="image-two"/>
              <img className="image-three"/>
             </Carousel>
           </div>
        );
      }
    

    【讨论】:

      【解决方案2】:

      useEffect 意思是:在这个组件被渲染后运行传递给useEffect的回调函数,并且由于你传递了一个空数组作为第二个参数,这意味着useEffect被执行一次,只有第一次这个组件被渲染(而不是在状态改变时),因为你的函数调用在 useEffect 中,它只有在你重新加载页面时才会起作用,你可以像 Mohamed Magdy 那样将变量添加到空数组中,或者简单地调用loadMediaQuery 又在外面useEffect

      【讨论】:

        【解决方案3】:

        扩展this answer中提供的自定义钩子,你可以做类似的事情

        const [width, height] = useWindowSize();
        
        useEffect(() => {
          loadMediaQuery();
        }, [width]);
        

        那个useEffect 函数说:每次width 的值改变时执行loadMediaQuery()

        【讨论】:

          猜你喜欢
          • 2020-09-12
          • 2023-02-22
          • 1970-01-01
          • 2021-04-24
          • 1970-01-01
          • 1970-01-01
          • 2019-09-16
          • 2023-03-09
          • 1970-01-01
          相关资源
          最近更新 更多