问题描述
尽管在stackoverflow上查找并遵循了许多答案,但我仍然无法重构此代码以遵守ESLint no-loop-func
。
尽管我努力重构代码,但我仍然收到以下警告:
Compiled with warnings.
Function declared in a loop contains unsafe references to variable(s) 'lastResult','biologyBooks','page' no-loop-func
这是代码:
import React from 'react';
import { apiFullCall } from '../../apiHelper';
const MyComponent = props => {
const [state,setState] = React.useState({ total: 0,biologyBooksByAuthor: [] });
let isLoaded = React.useRef(true);
const token = sessionStorage.getItem('token');
const authorID = sessionStorage.getItem('author_id');
const getBooks = async() => { // fetch items
let page = 1;
let scienceBooks,biologyBooks;
// create empty arrays to store book objects for each loop
let scienceBooks = biologyBooks = [];
// create a lastResult object to help check if there is a next page
let lastResult = { next: null };
do { // the looping - this is what I have Failed to refactor
try {
await apiFullCall( // Make API calls over paginated records
'',token,'get',`books/?author_id=1&page=${page}`
).then(res => {
if (res) {
const { status,body } = res;
if (status === 200 || status === 201) {
lastResult = body; // assign lastResult to pick "next"
body &&
body.results &&
body.results.map(eachBook => { // we map() over the returned "results" array
// the author with queried "author_id" writes science books;
// so we add each book (an object) into the science category
scienceBooks.push(eachBook);
// We then filter the author's biology books (from other science books)
biologyBooks = scienceBooks.filter(
({ is_biology }) =>
typeof(is_biology) === "boolean" && is_biology === true
);
return null;
}
);
// increment the page with 1 on each loop
page++;
}
}
}).catch(error => console.error('Error while fetching data:',error));
} catch (err) { console.error(`Oops,something went wrong ${err}`); }
// keep running until there's no next page
} while (lastResult.next !== null);
// update the state
setState(prevstate => ({
...prevstate,total: scienceBooks.length,biologyBooksByAuthor: biologyBooks,}));
};
React.useEffect(() => { // fetch science books by author (logged in)
if (isLoaded && authorID) {
getBooks();
};
return function cleanup() {...}; // clean up API call,on unmount
},[isLoaded,authorID]);
return (
// render the JSX code
);
}
请注意,我实际上是在“ do-while”之外声明了所述变量lastResult
,biologyBooks
和page
。
任何帮助或线索将不胜感激。
解决方法
警告所指的功能是.then
回调,如果您使用的是async/await
,请尝试通过将结果分配给变量来删除.then
部分并删除不必要的.map
,您可以使用传播运算符或.concat
合并先前的结果。
import React from 'react';
import { apiFullCall } from '../../apiHelper';
const MyComponent = props => {
const [state,setState] = React.useState({
total: 0,scienceBooksByAuthor: [],});
const isLoaded = React.useRef(true);
const token = sessionStorage.getItem('token');
const authorID = sessionStorage.getItem('author_id');
const getBooks = async () => {
// fetch items
let page = 1;
let scienceBooks = [];
// create a lastResult object to help check if there is a next page
let lastResult = { next: null };
do {
// the looping - this is what I have failed to refactor
try {
const res = await apiFullCall(
// Make API calls over paginated records
'',token,'get',`books/?author_id=1&page=${page}`,);
if (res) {
const { status,body } = res;
if (status === 200 || status === 201) {
lastResult = body; // assign lastResult to pick "next"
// concatenate new results
scienceBooks = [
...scienceBooks,...((lastResult && lastResult.results) || []),];
// increment the page with 1 on each loop
page += 1;
}
}
} catch (err) {
console.error(`Oops,something went wrong ${err}`);
}
// keep running until there's no next page
} while (lastResult.next !== null);
const biologyBooks = scienceBooks.filter(
({ is_biology }) =>
typeof is_biology === 'boolean' && is_biology === true,);
// update the state
setState(prevState => ({
...prevState,total: scienceBooks.length,scienceBooksByAuthor: scienceBooks,}));
};
React.useEffect(() => {
// fetch science books by author (logged in)
if (isLoaded && authorID) {
getBooks();
}
return function cleanup() {...}; // clean up API call,on unmount
},[isLoaded,authorID]);
return (
// render the JSX code
);
};