我制作了一个自定义钩子,将数据注册到由使用它的组件键控的存储中,然后在卸载组件时从存储中删除数据。基本都是这样
const [id] = useState(Math.random());
const setData = useCallback((data) => {
if(data) {
setRegistrations({
...registrations,
[id]: data
});
} else {
const {[id]: _, ...nextRegistrations} = registrations;
setRegistrations(nextRegistrations);
}
}, [id]);
useEffect(() => {
// update the registration if the data changed
setData(data);
}, [data, setData]);
useEffect(() => {
// remove the registration on unmount
setData();
}, []);
我正在使用 Math.random()
为每个使用我的钩子的组件生成一个唯一的 id,这工作正常,但我希望有一种方法可以找出使用我的钩子的组件的名称.如果我能看到哪个数据由哪个组件注册,那么调试我的应用程序状态会更容易,但我只需要查看一个随机小数。
现在我的商店看起来像这样
{
'0.5694216823063629': { ... }
'0.002760497537984463': { ... }
}
如果我能做这样的事情,我更愿意
{
'MyComponent-1': { ... }
'MyComponent-2': { ... }
'MyOtherComponent-1': { ... }
}
是的,我知道我可以让组件传入一个键,但这没有抓住重点。我希望 API 保持纯净而不污染它,以便调试更容易。
有没有办法找出哪个组件使用了我的钩子?
答案 0 :(得分:2)
函数和参数对象具有不推荐使用的属性,允许他们查看是谁调用了它们 - Function.caller 和 arguments.callee。但是,它们都在严格模式下被阻止。
你可以在抛出错误时从堆栈中获取调用者的名字,但这很丑陋,你应该只在开发模式下使用它。这仅适用于函数组件,但由于您在钩子中使用它,所以不会有问题。
示例(取自此 article):
// taken from https://devimalplanet.com/javascript-how-to-get-the-caller-parent-functions-name
function whoIsMyDaddy() {
try {
throw new Error();
} catch (e) {
// matches this function, the caller and the parent
const allMatches = e.stack.match(/(\w+)@|at (\w+) \(/g);
// match parent function name
const parentMatches = allMatches[2].match(/(\w+)@|at (\w+) \(/);
// return only name
return parentMatches[1] || parentMatches[2];
}
}
const useDemo = () => {
const daddy = whoIsMyDaddy()
React.useEffect(() => console.log(daddy))
}
const ComponentX = () => {
useDemo()
return 'X'
}
const ComponentY = () => {
useDemo()
return 'Y'
}
ReactDOM.render(
<div>
<ComponentX />
<ComponentY />
</div>,
root
)
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>
注意: 使用 Math.random()
作为 id 不是一个好主意,因为 Math.random()
不是那么随机 - 请参阅此 answer。您可以使用 Crypto.getRandomValues()
(如果支持)或外部 uuid 库。