是否有一种方法可以告诉react-hooks/exhaustive-deps
ESLint规则来警告我有关缺少deps
的自定义钩子用法的信息?例如:
function useCustomHook(callback, deps) {
...
useMemo(() => ..., deps);
...
}
// When using useCustomHook in a component:
function Component({ dep1, dep2, dep3 }) {
const res = useCustomHook(
() => dep1 + dep2 + dep3,
[]); // Even if this is a custom hook,
// I would like exhaustive-deps to warn me
// and tell me that I need to pass `dep1`, `dep2` and `dep3`
// to the deps array...
...
}
另一个例子:
我有以下自定义钩子,可用于在功能性React组件中实现抽象工厂:
/**
* Usage:
*
* const choice1 = {
* color: "red",
* label: "Fire"
* };
*
* const choice2 = {
* color: "green",
* label: "Grass"
* }
*
* const choice3 = {
* color: "blue",
* label: "Water"
* }
*
* const factory = useFactory(() => [
* [dep1, choice1],
* [dep2, choice2],
* [dep3, choice3]
* ], [dep1, dep2, dep3]);
*
* // Assuming dep1 = false, dep2 = true and dep3 = false:
* factory === choice2 // true
*/
export default function useFactory(tuplesFn, deps) {
const tuples = useMemo(tuplesFn, deps);
// "testConditionFn" is pure and does never change.
const testConditionFn = useCallback(
testCondition =>
Boolean(
typeof testCondition === "function" ? testCondition() : testCondition
),
[]
);
const factoryValue = useMemo(() => {
let i = 0;
// Loop through all the tuples except the last one (handled after this loop).
for (; i < tuples.length - 1; i++) {
const tuple = tuples[i];
const [testCondition, factoryValue] = tuple;
if (testConditionFn(testCondition)) {
// Test condition for factory value is satisfied.
return factoryValue;
}
}
const lastTuple = tuples[i];
if (isArray(lastTuple) && lastTuple.length === 2) {
const [testCondition, factoryValue] = lastTuple;
if (testConditionFn(testCondition)) {
// Test condition for last factory value is satisfied.
return factoryValue;
}
// No default and no factory value satisfying a test condition.
return void 0;
} else {
// Default factory value.
return lastTuple;
}
}, [testConditionFn, tuples]);
return factoryValue;
}
它的工作原理如下(Codesandbox:https://codesandbox.io/s/react-example-8o9ht):
import ReactDOM from "react-dom";
import React, { useMemo } from "react";
import { useFactory } from "react-js-utl/hooks";
const choice1 = {
color: "red",
label: "Fire"
};
const choice2 = {
color: "green",
label: "Grass"
};
const choice3 = {
color: "blue",
label: "Water"
};
function Example({ dep1, dep2, dep3 }) {
const factoryValue = useFactory(
() => [[dep1, choice1], [dep2, choice2], [() => dep3, choice3], "default"],
// How to tell react-hooks/exhaustive-deps that it should warn me
// that this array of deps is missing `dep1`, `dep2` and `dep3`?
[] // No warning, but there should be one...
);
// Builtin `useMemo` hook works as expected.
// react-hooks/exhaustive-deps warns me that the deps array is missing `dep1`, `dep2` and `dep3`:
//
// React Hook useMemo has missing dependencies: 'dep1', 'dep2', and 'dep3'.
// Either include them or remove the dependency array. (react-hooks/exhaustive-deps)eslint
//
const dummyMemoizedValue = useMemo(() => (dep1 ? dep3 : dep2), []);
return (
<div>
{JSON.stringify(factoryValue)} - {JSON.stringify(dummyMemoizedValue)}
</div>
);
}
ReactDOM.render(
<Example dep1={false} dep2={true} dep3={false} />,
document.getElementById("root")
);
factoryValue
是{ color: "green", label:"Grass" }
,因为dep2
是唯一的真实道具,而choice2
是useFactory
返回的对象。
但是useFactory
自定义钩子缺少在其回调中使用的依赖项dep1
,dep2
和dep3
,它们可能在重新渲染之间改变,因此该组件可能会呈现过时的数据。
如果有办法的话,我想react-hooks/exhaustive-deps
提醒我。
谢谢!