I am designing a hook to fetch data only when the hooks dependencies change. It works as expected but I receive the linter warnings:
React Hook useEffect was passed a dependency list that is not an array literal. This means we can't statically verify whether you've passed the correct dependencies.
and
React Hook useEffect has missing dependencies: 'data', 'errorHandler', 'route', and 'successHandler'. Either include them or remove the dependency array. If 'successHandler' changes too often, find the parent ponent that defines it and wrap that definition in useCallback.
As far as I am aware I do not want all these vars in my dependencies as I don't want to fire this hook when these change, I only want to fire it when the dependencies I pass change.
Question:
How can I design useFetch()
hook in a way that coincides with the hooks linter standards (if my design pattern is not up to par, please elaborate on how best this should be acplished).
My useFetch()
hook
function useFetch(
{
route,
data = {},
successHandler,
errorHandler,
},
dependencies = []) {
const [loading, setLoading] = useState(true);
useEffect(() => {
setLoading(true);
postJson({route}, data)
.then(
res => {
if(isFunction(successHandler)) successHandler(res);
},
({responseJSON: err}) => {
if(isFunction(errorHandler)) {
errorHandler(err);
} else {
notify({text: err.message || messages.saveFailed(), cssClass: 'error'});
}
}
)
.finally(() => {
setLoading(false);
});
}, dependencies);
return loading;
}
Component using useFetch()
function MyComponent({data, selectedReviewId, setField}) {
const loading = useFetch({
route: 'foo.fetchData',
data: {crrType, clientId, programId, userId},
successHandler: d => setField([], d) // setField() will set data with the value fetched in useFetch()
}, [selectedReviewId]);
return loading ? <SpinnerComponent/> : <div>{data.foo}</div>;
}
I am designing a hook to fetch data only when the hooks dependencies change. It works as expected but I receive the linter warnings:
React Hook useEffect was passed a dependency list that is not an array literal. This means we can't statically verify whether you've passed the correct dependencies.
and
React Hook useEffect has missing dependencies: 'data', 'errorHandler', 'route', and 'successHandler'. Either include them or remove the dependency array. If 'successHandler' changes too often, find the parent ponent that defines it and wrap that definition in useCallback.
As far as I am aware I do not want all these vars in my dependencies as I don't want to fire this hook when these change, I only want to fire it when the dependencies I pass change.
Question:
How can I design useFetch()
hook in a way that coincides with the hooks linter standards (if my design pattern is not up to par, please elaborate on how best this should be acplished).
My useFetch()
hook
function useFetch(
{
route,
data = {},
successHandler,
errorHandler,
},
dependencies = []) {
const [loading, setLoading] = useState(true);
useEffect(() => {
setLoading(true);
postJson({route}, data)
.then(
res => {
if(isFunction(successHandler)) successHandler(res);
},
({responseJSON: err}) => {
if(isFunction(errorHandler)) {
errorHandler(err);
} else {
notify({text: err.message || messages.saveFailed(), cssClass: 'error'});
}
}
)
.finally(() => {
setLoading(false);
});
}, dependencies);
return loading;
}
Component using useFetch()
function MyComponent({data, selectedReviewId, setField}) {
const loading = useFetch({
route: 'foo.fetchData',
data: {crrType, clientId, programId, userId},
successHandler: d => setField([], d) // setField() will set data with the value fetched in useFetch()
}, [selectedReviewId]);
return loading ? <SpinnerComponent/> : <div>{data.foo}</div>;
}
Share
Improve this question
asked Sep 18, 2019 at 1:05
Miroslav GlamuzinaMiroslav Glamuzina
4,5872 gold badges21 silver badges33 bronze badges
1
-
My suggestion's are, anyways you have staticlly assigning empty array to dependencies variable and then provided that variable as dependency array, you should directly provide empty array. Another is don't destructure your props, instead you can use
props.data
,props.route
in useEffect directy. – ravibagul91 Commented Sep 18, 2019 at 1:40
2 Answers
Reset to default 3You have passed dependency as array but on the receiving end, it's essentially a single variable pointing to an array. Lint rule of useEffect()
requires that you pass dependencies in square brackets like done in following code.
Now some technical stuff. Remember what's generating the warning. It's the lint which checks code syntactically. It doesn't go into semantics. Semantically, your list of dependencies is correct, as you are passing an array but syntactically, it's not being passed as an array i.e. it's a single variable not passed in square brackets (like this [dependencies]
) (which is something lint is looking for). So in order to satisfy lint, you should write:
useEffect(
() => { // implementation of function },
[dependencies]
);
Further, as you are sending an array of dependencies, you can also use spread operator, like this:
useEffect(
() => { // implementation of function },
[...dependencies]
);
This will spread the array elements inside array operator by Babel transpiler. Lint will also remain quiet.
The eslint
warning is right - you should include those as dependencies. For example, in your MyComponent
if data
changes, and it is not in your dependency list, your useEffect
hook will be calling fetch will outdated data
.
Same applies to others - it's advised to add those to your dependencies list.
For the first error, it is probably ok - even though not ideal. You have a dynamic dependencies list - eslint
can't be sure if you have all the required stuff in there.
Your solution is probably going to work - but it is very fragile. If your dependencies
happen to change (e.g. additional elements, or removed elements)
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745263238a4619309.html
评论列表(0条)