Enable react hooks linting

Summary:
Enabled linting rules that help to signal making errors with effect dependencies and such.

Fixed all errors, left any warnings generated by the hooks untouched

Reviewed By: nikoant

Differential Revision: D21721497

fbshipit-source-id: 9548453443fa7b663dc4d4289132f388c6697283
This commit is contained in:
Michel Weststrate
2020-05-28 10:12:10 -07:00
committed by Facebook GitHub Bot
parent 67b53aea98
commit 54162d480c
6 changed files with 49 additions and 35 deletions

View File

@@ -46,10 +46,13 @@ module.exports = {
'@typescript-eslint',
'import',
'node',
'react-hooks',
],
rules: {
// disable rules from eslint-config-fbjs
'react/react-in-jsx-scope': 0, // not needed with our metro implementation
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
'no-new': 0, // new keyword needed e.g. new Notification
'no-catch-shadow': 0, // only relevant for IE8 and below
'no-bitwise': 0, // bitwise operations needed in some places

View File

@@ -142,7 +142,7 @@ export function annotatePluginsWithUpdates(
return new Map(annotated);
}
const PluginInstaller = function props(props: Props) {
const PluginInstaller = function (props: Props) {
const [restartRequired, setRestartRequired] = useState(false);
const [query, setQuery] = useState('');

View File

@@ -165,8 +165,10 @@ export default function Tabs(props: {
*/
classic?: boolean;
}) {
const tabsContainer =
props.classic === true ? false : useContext(TabsContext);
let tabsContainer = useContext(TabsContext);
if (props.classic === true) {
tabsContainer = false;
}
const {onActive} = props;
const active: string | undefined =

View File

@@ -172,6 +172,7 @@
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.1.2",
"eslint-plugin-react": "^7.20.0",
"eslint-plugin-react-hooks": "^4.0.2",
"eslint-plugin-relay": "^1.4.1",
"express": "^4.15.2",
"flipper-babel-transformer": "0.44.0",

View File

@@ -98,56 +98,55 @@ type Props = {
const Sidebar: React.FC<Props> = (props: Props) => {
const {element} = props;
if (!element || !element.data) {
return <NoData grow>No data</NoData>;
}
const [sectionDefs, sectionKeys] = useMemo(() => {
const sectionKeys = [];
const sectionDefs = [];
for (const key in element.data) {
if (key === 'Extra Sections') {
for (const extraSection in element.data[key]) {
const section = element.data[key][extraSection];
let data = {};
if (element && element.data)
for (const key in element.data) {
if (key === 'Extra Sections') {
for (const extraSection in element.data[key]) {
const section = element.data[key][extraSection];
let data = {};
// data might be sent as stringified JSON, we want to parse it for a nicer persentation.
if (typeof section === 'string') {
try {
data = JSON.parse(section);
} catch (e) {
// data was not a valid JSON, type is required to be an object
console.error(
`ElementsInspector unable to parse extra section: ${extraSection}`,
);
data = {};
// data might be sent as stringified JSON, we want to parse it for a nicer persentation.
if (typeof section === 'string') {
try {
data = JSON.parse(section);
} catch (e) {
// data was not a valid JSON, type is required to be an object
console.error(
`ElementsInspector unable to parse extra section: ${extraSection}`,
);
data = {};
}
} else {
data = section;
}
} else {
data = section;
sectionKeys.push(kebabCase(extraSection));
sectionDefs.push({
key: extraSection,
id: extraSection,
data: data,
});
}
sectionKeys.push(kebabCase(extraSection));
} else {
sectionKeys.push(kebabCase(key));
sectionDefs.push({
key: extraSection,
id: extraSection,
data: data,
key,
id: key,
data: element.data[key],
});
}
} else {
sectionKeys.push(kebabCase(key));
sectionDefs.push({
key,
id: key,
data: element.data[key],
});
}
}
return [sectionDefs, sectionKeys];
}, [props.element]);
const sections: Array<React.ReactNode> = (
(SidebarExtensions &&
element?.data &&
SidebarExtensions.map((ext) =>
ext(props.client, props.realClient, element, props.logger),
)) ||
@@ -169,6 +168,10 @@ const Sidebar: React.FC<Props> = (props: Props) => {
props.logger.track('usage', `layout-sidebar-extension:${key}:loaded`),
);
}, [props.element?.data]);
if (!element || !element.data) {
return <NoData grow>No data</NoData>;
}
return <>{sections}</>;
};

View File

@@ -5312,6 +5312,11 @@ eslint-plugin-prettier@^3.1.1, eslint-plugin-prettier@^3.1.2:
dependencies:
prettier-linter-helpers "^1.0.0"
eslint-plugin-react-hooks@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.0.2.tgz#03700ca761eacc1b6436074c456f90a8e331ff28"
integrity sha512-kAMRjNztrLW1rK+81X1NwMB2LqG+nc7Q8AibnG8/VyWhQK8SP6JotCFG+HL4u1EjziplxVz4jARdR8gGk8pLDA==
eslint-plugin-react@^7.20.0:
version "7.20.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.20.0.tgz#f98712f0a5e57dfd3e5542ef0604b8739cd47be3"