useEffect死循环问题

const {visible} = props;
const [dateRange, setDateRange] = useState([moment(), moment()]);

    useEffect(() => {
        const getData = async () => {
            const res = await fetch({ start: dateRange[0].valueOf(), end: dateRange[1].valueOf()});
        }
        if(visible){
            // 每次出现的时候都重置dateRange值
            setInputValue([moment(),moment()])
            // 每次出现的时候都请求接口
            getData()
        }
    }, [visible, dateRange]);

    const handleInputChange = (value) => {
        setDateRange(value);
    }
    return (
        <div style={{ display: 'flex' }}>
            <DateRange value={dateRange} onChange={handleInputChange}></DateRange>
        </div>
    );

由于每次dateRange都是新数组,导致每次dateRange都是新的,useEffect会死循环,如何解决?

阅读 6.8k
2 个回答

依赖项改成直接依赖dateRange的元素

const {visible} = props;
const [dateRange, setDateRange] = useState([moment(), moment()]);

    useEffect(() => {
        const getData = async () => {
            const res = await fetch({ start: dateRange[0].valueOf(), end: dateRange[1].valueOf()});
        }
        if(visible){
            // 每次出现的时候都重置dateRange值
            setInputValue([moment(),moment()])
            // 每次出现的时候都请求接口
            getData()
        }
    }, [visible, dateRange[0], dateRange[1]);

    const handleInputChange = (value) => {
        setDateRange(value);
    }
    return (
        <div style={{ display: 'flex' }}>
            <DateRange value={dateRange} onChange={handleInputChange}></DateRange>
        </div>
    );

PS:
看代码逻辑useEffect本质只依赖变量visible,代码可以调整为:

const {visible} = props;
const [dateRange, setDateRange] = useState([moment(), moment()]);

const getData = async () => {
            const res = await fetch({ start: dateRange[0].valueOf(), end: dateRange[1].valueOf()});
        }
        
    useEffect(() => {               
        if(visible){
            // 每次出现的时候都重置dateRange值
            setInputValue([moment(),moment()])
            // 每次出现的时候都请求接口
            getData()
        }
    }, [visible]);

    const handleInputChange = (value) => {
        setDateRange(value);
    }
    return (
        <div style={{ display: 'flex' }}>
            <DateRange value={dateRange} onChange={handleInputChange}></DateRange>
        </div>
    );

每次 visible 变化的时候,要拿到最新的 date 值进行请求,同时重置,意味这多次渲染需要共享一个 immutable 值,完全可以用 useRef 存储而不触发依赖

const defaultDateRange = [moment(), moment()]
const { visible } = props;
const [dateRange, setDateRange] = useState(defaultDateRange);
const dateRangeRef = useRef(defaultDateRange)

useEffect(() => {
  const getData = async () => {
    const res = await fetch({
      start: dateRangeRef.current[0].valueOf(),
      end: dateRangeRef.current[1].valueOf(),
    });
  };
  if (visible) {
    // 每次出现的时候都重置dateRange值
    dateRangeRef.current = defaultDateRange;
    setDateRange(defaultDateRange);
    // 每次出现的时候都请求接口
    getData();
  }
}, [visible]);

const handleInputChange = (value) => {
  dateRangeRef.current = value;
  setDateRange(value);

};
return (
  <div style={{ display: 'flex' }}>
    <DateRange value={dateRange} onChange={handleInputChange}></DateRange>
  </div>
);
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题