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(), []);