Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 反应:每当我使用moment时,自定义钩子都会继续执行_Reactjs_Momentjs - Fatal编程技术网

Reactjs 反应:每当我使用moment时,自定义钩子都会继续执行

Reactjs 反应:每当我使用moment时,自定义钩子都会继续执行,reactjs,momentjs,Reactjs,Momentjs,这是我的自定义挂钩和组件: import React, { useCallback, useState, useEffect } from "react"; import moment from "moment"; const useMyHook = ({ foobar } = {}) => { const [loading, setLoading] = useState(true); const [error, setError] = u

这是我的自定义挂钩和组件:

import React, { useCallback, useState, useEffect } from "react";
import moment from "moment";

const useMyHook = ({ foobar } = {}) => {
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [data, setData] = useState([]);
  const [count, setCount] = useState(0);

  const fetchStuff = useCallback(
    async ({ foobar }) => {
      try {
        console.log("TRY");
        setData([]);
        setCount(0);
      } catch (e) {
        console.log("ERROR", e);
        setError(e);
      } finally {
        console.log("FINALLY");
        setLoading(false);
      }
    },
    [setError, setCount, setData, setLoading]
  );

  useEffect(() => {
    console.log("USE EFFECT");
    fetchStuff({ foobar });
  }, [fetchStuff, foobar]);

  return {
    loading,
    error,
    count,
    data,
    refresh: fetchStuff
  };
};

export default function App() {
  console.log("RENDERING");

  // COMMENT THIS IN TO SEE BUG
  // const foobar = moment().valueOf();
  // const { loading, error, data, refresh } = useMyHook({ foobar });

  // COMMENT THIS OUT
  const { loading, error, data, refresh } = useMyHook({ foobar: 123 });

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

如果我替换
useMyHook({foobar})使用类似于这样的harcoded int:
useMyHook({foobar:123})
一切正常。然而,如果我使用矩,如果您运行下面我的沙盒链接并查看控制台,它就会溢出

我做错了什么

沙箱:


矩将在每次调用时返回当前时间,这将触发
useMyHook
中的效果,导致重新渲染,导致另一个矩调用,…,以及无限循环。只需将第一次调用缓存到某个地方即可解决此问题。建议使用带有值工厂的state,但memo也可以

const [foobar, updateFoobar] = useState(() => moment().subtract(1, 'month').valueOf());
const foobar = useMemo(() => moment().subtract(1, 'month').valueOf(), []);

“时刻”调用不是每次调用时都返回一个新值吗?IIRC我认为,
moment()
将只返回当前时间,这将是每次调用渲染时的一个新值。这很有意义。因此,我必须从钩子本身中设置默认日期,而不是传递一个从组件动态生成的日期。您也可以从应用程序中
usemo
<代码>使用备忘录(()=>moment()。减去(1,'月')。valueOf(),[])
好的调用。我从未使用过useMemo,它看起来是放置默认日期的好地方
const [foobar, updateFoobar] = useState(() => moment().subtract(1, 'month').valueOf());
const foobar = useMemo(() => moment().subtract(1, 'month').valueOf(), []);