[APM] Add react-hooks lint rules for APM folder, fix dependencies (#42129)

* [APM] Add react-hooks lint rules for APM folder, fix dependencies

Closes #42128.

* Validate useFetcher dependencies as well

* Add useFetcher hook; move eslint config to kibana eslint config
This commit is contained in:
Dario Gieselaar 2019-07-29 20:36:24 +02:00 committed by GitHub
parent c91c08f17a
commit b6258b2125
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 45 additions and 23 deletions

View file

@ -396,6 +396,14 @@ module.exports = {
'no-console': ['warn', { allow: ['error'] }], 'no-console': ['warn', { allow: ['error'] }],
}, },
}, },
{
plugins: ['react-hooks'],
files: ['x-pack/legacy/plugins/apm/**/*.{ts,tsx}'],
rules: {
'react-hooks/rules-of-hooks': 'error', // Checks rules of Hooks
'react-hooks/exhaustive-deps': ['error', { additionalHooks: '^useFetcher$' }],
},
},
/** /**
* GIS overrides * GIS overrides

View file

@ -11,6 +11,7 @@ import { useCore } from '../../../hooks/useCore';
export const useUpdateBadgeEffect = () => { export const useUpdateBadgeEffect = () => {
const { chrome } = useCore(); const { chrome } = useCore();
useEffect(() => { useEffect(() => {
const uiCapabilities = capabilities.get(); const uiCapabilities = capabilities.get();
chrome.setBadge( chrome.setBadge(
@ -26,5 +27,5 @@ export const useUpdateBadgeEffect = () => {
} }
: undefined : undefined
); );
}, []); }, [chrome]);
}; };

View file

@ -70,7 +70,7 @@ export function ServiceOverview() {
) )
}); });
} }
}, [data.hasLegacyData]); }, [data.hasLegacyData, core.http.basePath]);
useTrackPageview({ app: 'apm', path: 'services_overview' }); useTrackPageview({ app: 'apm', path: 'services_overview' });
useTrackPageview({ app: 'apm', path: 'services_overview', delay: 15000 }); useTrackPageview({ app: 'apm', path: 'services_overview', delay: 15000 });

View file

@ -47,10 +47,6 @@ export function AddSettingsFlyout({
onSubmit, onSubmit,
selectedConfig selectedConfig
}: Props) { }: Props) {
if (!isOpen) {
return null;
}
const [environment, setEnvironment] = useState<string | undefined>( const [environment, setEnvironment] = useState<string | undefined>(
selectedConfig selectedConfig
? selectedConfig.service.environment || ENVIRONMENT_NOT_DEFINED ? selectedConfig.service.environment || ENVIRONMENT_NOT_DEFINED
@ -88,6 +84,11 @@ export function AddSettingsFlyout({
const hasCorrectDecimals = Number.isInteger(sampleRateFloat * 1000); const hasCorrectDecimals = Number.isInteger(sampleRateFloat * 1000);
const isSampleRateValid = const isSampleRateValid =
sampleRateFloat >= 0 && sampleRateFloat <= 1 && hasCorrectDecimals; sampleRateFloat >= 0 && sampleRateFloat <= 1 && hasCorrectDecimals;
if (!isOpen) {
return null;
}
return ( return (
<EuiPortal> <EuiPortal>
<EuiFlyout size="s" onClose={onClose} ownFocus={true}> <EuiFlyout size="s" onClose={onClose} ownFocus={true}>

View file

@ -25,11 +25,10 @@ const TransactionNameLink = styled(TransactionLink)`
interface Props { interface Props {
items: ITransactionGroup[]; items: ITransactionGroup[];
serviceName: string;
isLoading: boolean; isLoading: boolean;
} }
export function TransactionList({ items, serviceName, isLoading }: Props) { export function TransactionList({ items, isLoading }: Props) {
const columns: Array<ITableColumn<ITransactionGroup>> = useMemo( const columns: Array<ITableColumn<ITransactionGroup>> = useMemo(
() => [ () => [
{ {
@ -39,7 +38,7 @@ export function TransactionList({ items, serviceName, isLoading }: Props) {
}), }),
width: '50%', width: '50%',
sortable: true, sortable: true,
render: (transactionName: string, item: typeof items[0]) => { render: (transactionName: string, item: ITransactionGroup) => {
return ( return (
<EuiToolTip <EuiToolTip
id="transaction-name-link-tooltip" id="transaction-name-link-tooltip"
@ -104,7 +103,7 @@ export function TransactionList({ items, serviceName, isLoading }: Props) {
render: (value: number) => <ImpactBar value={value} /> render: (value: number) => <ImpactBar value={value} />
} }
], ],
[serviceName] []
); );
const noItemsMessage = ( const noItemsMessage = (

View file

@ -152,7 +152,6 @@ export function TransactionOverview({ urlParams }: Props) {
<TransactionList <TransactionList
isLoading={transactionListStatus === 'loading'} isLoading={transactionListStatus === 'loading'}
items={transactionListData} items={transactionListData}
serviceName={serviceName}
/> />
</EuiPanel> </EuiPanel>
</React.Fragment> </React.Fragment>

View file

@ -120,15 +120,19 @@ export function KueryBar() {
let didCancel = false; let didCancel = false;
async function loadIndexPattern() { async function loadIndexPattern() {
setState({ ...state, isLoadingIndexPattern: true }); setState(value => ({ ...value, isLoadingIndexPattern: true }));
const indexPattern = await getAPMIndexPatternForKuery(); const indexPattern = await getAPMIndexPatternForKuery();
if (didCancel) { if (didCancel) {
return; return;
} }
if (!indexPattern) { if (!indexPattern) {
setState({ ...state, isLoadingIndexPattern: false }); setState(value => ({ ...value, isLoadingIndexPattern: false }));
} else { } else {
setState({ ...state, indexPattern, isLoadingIndexPattern: false }); setState(value => ({
...value,
indexPattern,
isLoadingIndexPattern: false
}));
} }
} }
loadIndexPattern(); loadIndexPattern();

View file

@ -47,17 +47,19 @@ const UrlParamsProvider: React.ComponentClass<{}> = withRouter(
({ location, children }) => { ({ location, children }) => {
const refUrlParams = useRef(resolveUrlParams(location, {})); const refUrlParams = useRef(resolveUrlParams(location, {}));
const { start, end, rangeFrom, rangeTo } = refUrlParams.current;
const [, forceUpdate] = useState(''); const [, forceUpdate] = useState('');
const urlParams = useMemo( const urlParams = useMemo(
() => () =>
resolveUrlParams(location, { resolveUrlParams(location, {
start: refUrlParams.current.start, start,
end: refUrlParams.current.end, end,
rangeFrom: refUrlParams.current.rangeFrom, rangeFrom,
rangeTo: refUrlParams.current.rangeTo rangeTo
}), }),
[location, refUrlParams.current] [location, start, end, rangeFrom, rangeTo]
); );
refUrlParams.current = urlParams; refUrlParams.current = urlParams;

View file

@ -74,14 +74,22 @@ export function useFetcher<Response>(
dispatchStatus({ id, isLoading: false }); dispatchStatus({ id, isLoading: false });
didCancel = true; didCancel = true;
}; };
}, [...effectKey, counter]); /* eslint-disable react-hooks/exhaustive-deps */
}, [
counter,
id,
preservePreviousResponse,
dispatchStatus,
...effectKey
/* eslint-enable react-hooks/exhaustive-deps */
]);
return useMemo( return useMemo(
() => ({ () => ({
...result, ...result,
refresh: () => { refresh: () => {
// this will invalidate the effectKey and will result in a new request // this will invalidate the effectKey and will result in a new request
setCounter(counter + 1); setCounter(count => count + 1);
} }
}), }),
[result] [result]

View file

@ -30,7 +30,7 @@ export function useTransactionBreakdown() {
uiFilters uiFilters
}); });
} }
}, [serviceName, start, end, uiFilters]); }, [serviceName, start, end, transactionType, transactionName, uiFilters]);
const receivedDataDuringLifetime = useRef(false); const receivedDataDuringLifetime = useRef(false);

View file

@ -31,7 +31,7 @@ export function useTransactionCharts() {
const memoizedData = useMemo( const memoizedData = useMemo(
() => getTransactionCharts({ transactionType }, data), () => getTransactionCharts({ transactionType }, data),
[data] [data, transactionType]
); );
return { return {