diff --git a/x-pack/plugins/security_solution/public/cases/components/use_all_cases_modal/index.tsx b/x-pack/plugins/security_solution/public/cases/components/use_all_cases_modal/index.tsx index f7fc7963b3844..445ae675007cc 100644 --- a/x-pack/plugins/security_solution/public/cases/components/use_all_cases_modal/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/use_all_cases_modal/index.tsx @@ -5,13 +5,13 @@ */ import React, { useState, useCallback, useMemo } from 'react'; +import { useDispatch } from 'react-redux'; -import { useDispatch, useSelector } from 'react-redux'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { APP_ID } from '../../../../common/constants'; import { SecurityPageName } from '../../../app/types'; import { useKibana } from '../../../common/lib/kibana'; import { getCaseDetailsUrl, getCreateCaseUrl } from '../../../common/components/link_to'; -import { State } from '../../../common/store'; import { setInsertTimeline } from '../../../timelines/store/timeline/actions'; import { timelineSelectors } from '../../../timelines/store/timeline'; @@ -34,7 +34,7 @@ export const useAllCasesModal = ({ }: UseAllCasesModalProps): UseAllCasesModalReturnedValues => { const dispatch = useDispatch(); const { navigateToApp } = useKibana().services.application; - const timeline = useSelector((state: State) => + const timeline = useShallowEqualSelector((state) => timelineSelectors.selectTimeline(state, timelineId) ); diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_get_url_search.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_get_url_search.tsx index 099c9ee3fca0a..84f691dcd72e1 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_get_url_search.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_get_url_search.tsx @@ -4,17 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isEqual } from 'lodash/fp'; import { useMemo } from 'react'; -import { useSelector } from 'react-redux'; +import { useDeepEqualSelector } from '../../hooks/use_selector'; import { makeMapStateToProps } from '../url_state/helpers'; import { getSearch } from './helpers'; import { SearchNavTab } from './types'; export const useGetUrlSearch = (tab: SearchNavTab) => { const mapState = makeMapStateToProps(); - const { urlState } = useSelector(mapState, isEqual); + const { urlState } = useDeepEqualSelector(mapState); const urlSearch = useMemo(() => getSearch(tab, urlState), [tab, urlState]); return urlSearch; }; diff --git a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx index 4b1db8a2871bd..c36e2de61fcbf 100644 --- a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx @@ -8,7 +8,7 @@ import { set } from '@elastic/safer-lodash-set/fp'; import { keyBy, pick, isEmpty, isEqual, isUndefined } from 'lodash/fp'; import memoizeOne from 'memoize-one'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { useDispatch, useSelector, shallowEqual } from 'react-redux'; +import { useDispatch } from 'react-redux'; import { IIndexPattern } from 'src/plugins/data/public'; import { useKibana } from '../../lib/kibana'; @@ -20,11 +20,10 @@ import { BrowserFields, } from '../../../../common/search_strategy/index_fields'; import { AbortError } from '../../../../../../../src/plugins/data/common'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import * as i18n from './translations'; import { SourcererScopeName } from '../../store/sourcerer/model'; import { sourcererActions, sourcererSelectors } from '../../store/sourcerer'; - -import { State } from '../../store'; import { DocValueFields } from '../../../../common/search_strategy/common'; export { BrowserField, BrowserFields, DocValueFields }; @@ -201,9 +200,8 @@ export const useIndexFields = (sourcererScopeName: SourcererScopeName) => { () => sourcererSelectors.getIndexNamesSelectedSelector(), [] ); - const indexNames = useSelector( - (state) => indexNamesSelectedSelector(state, sourcererScopeName), - shallowEqual + const indexNames = useShallowEqualSelector((state) => + indexNamesSelectedSelector(state, sourcererScopeName) ); const setLoading = useCallback( diff --git a/x-pack/plugins/security_solution/public/common/containers/use_full_screen/index.tsx b/x-pack/plugins/security_solution/public/common/containers/use_full_screen/index.tsx index 32591fb032436..8357a9d22739e 100644 --- a/x-pack/plugins/security_solution/public/common/containers/use_full_screen/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/use_full_screen/index.tsx @@ -5,9 +5,10 @@ */ import { useCallback, useMemo } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { SCROLLING_DISABLED_CLASS_NAME } from '../../../../common/constants'; +import { useDispatch } from 'react-redux'; +import { SCROLLING_DISABLED_CLASS_NAME } from '../../../../common/constants'; +import { useShallowEqualSelector } from '../../hooks/use_selector'; import { inputsSelectors } from '../../store'; import { inputsActions } from '../../store/actions'; @@ -29,8 +30,10 @@ export const resetScroll = () => { export const useFullScreen = () => { const dispatch = useDispatch(); - const globalFullScreen = useSelector(inputsSelectors.globalFullScreenSelector) ?? false; - const timelineFullScreen = useSelector(inputsSelectors.timelineFullScreenSelector) ?? false; + const globalFullScreen = + useShallowEqualSelector(inputsSelectors.globalFullScreenSelector) ?? false; + const timelineFullScreen = + useShallowEqualSelector(inputsSelectors.timelineFullScreenSelector) ?? false; const setGlobalFullScreen = useCallback( (fullScreen: boolean) => { diff --git a/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.tsx b/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.tsx index 52825caf9ce74..e6c47c697c0b2 100644 --- a/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.tsx @@ -5,15 +5,16 @@ */ import { useCallback, useState, useEffect, useMemo } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; +import { useShallowEqualSelector } from '../../hooks/use_selector'; import { inputsSelectors } from '../../store'; import { inputsActions } from '../../store/actions'; import { SetQuery, DeleteQuery } from './types'; export const useGlobalTime = (clearAllQuery: boolean = true) => { const dispatch = useDispatch(); - const { from, to } = useSelector(inputsSelectors.globalTimeRangeSelector); + const { from, to } = useShallowEqualSelector(inputsSelectors.globalTimeRangeSelector); const [isInitializing, setIsInitializing] = useState(true); const setQuery = useCallback( diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_selector.tsx b/x-pack/plugins/security_solution/public/common/hooks/use_selector.tsx new file mode 100644 index 0000000000000..d5416acb69d14 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/hooks/use_selector.tsx @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { shallowEqual, useSelector } from 'react-redux'; +import deepEqual from 'fast-deep-equal'; +import { State } from '../store'; + +export type TypedUseSelectorHook = ( + selector: (state: TState) => TSelected, + equalityFn?: (left: TSelected, right: TSelected) => boolean +) => TSelected; + +export const useShallowEqualSelector: TypedUseSelectorHook = (selector) => + useSelector(selector, shallowEqual); + +export const useDeepEqualSelector: TypedUseSelectorHook = (selector) => + useSelector(selector, deepEqual); diff --git a/x-pack/plugins/security_solution/public/hosts/containers/authentications/index.tsx b/x-pack/plugins/security_solution/public/hosts/containers/authentications/index.tsx index b1563e85c93dd..bc7137097c646 100644 --- a/x-pack/plugins/security_solution/public/hosts/containers/authentications/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/containers/authentications/index.tsx @@ -6,7 +6,6 @@ import { noop } from 'lodash/fp'; import { useCallback, useEffect, useRef, useState } from 'react'; -import { shallowEqual, useSelector } from 'react-redux'; import deepEqual from 'fast-deep-equal'; import { @@ -26,7 +25,8 @@ import { } from '../../../../common/search_strategy'; import { ESTermQuery } from '../../../../common/typed_json'; -import { inputsModel, State } from '../../../common/store'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; +import { inputsModel } from '../../../common/store'; import { createFilter } from '../../../common/containers/helpers'; import { generateTablePaginationOptions } from '../../../common/components/paginated_table/helpers'; import { useKibana } from '../../../common/lib/kibana'; @@ -71,9 +71,8 @@ export const useAuthentications = ({ skip, }: UseAuthentications): [boolean, AuthenticationArgs] => { const getAuthenticationsSelector = hostsSelectors.authenticationsSelector(); - const { activePage, limit } = useSelector( - (state: State) => getAuthenticationsSelector(state, type), - shallowEqual + const { activePage, limit } = useShallowEqualSelector((state) => + getAuthenticationsSelector(state, type) ); const { data, notifications } = useKibana().services; const refetch = useRef(noop); diff --git a/x-pack/plugins/security_solution/public/hosts/containers/hosts/index.tsx b/x-pack/plugins/security_solution/public/hosts/containers/hosts/index.tsx index 6ca0272e58d7d..77f4567fc6a5f 100644 --- a/x-pack/plugins/security_solution/public/hosts/containers/hosts/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/containers/hosts/index.tsx @@ -7,11 +7,11 @@ import deepEqual from 'fast-deep-equal'; import { noop } from 'lodash/fp'; import { useCallback, useEffect, useRef, useState } from 'react'; -import { useSelector } from 'react-redux'; import { inputsModel, State } from '../../../common/store'; import { createFilter } from '../../../common/containers/helpers'; import { useKibana } from '../../../common/lib/kibana'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { hostsModel, hostsSelectors } from '../../store'; import { generateTablePaginationOptions } from '../../../common/components/paginated_table/helpers'; import { @@ -69,7 +69,7 @@ export const useAllHost = ({ type, }: UseAllHost): [boolean, HostsArgs] => { const getHostsSelector = hostsSelectors.hostsSelector(); - const { activePage, direction, limit, sortField } = useSelector((state: State) => + const { activePage, direction, limit, sortField } = useShallowEqualSelector((state: State) => getHostsSelector(state, type) ); const { data, notifications } = useKibana().services; diff --git a/x-pack/plugins/security_solution/public/network/components/network_dns_table/index.tsx b/x-pack/plugins/security_solution/public/network/components/network_dns_table/index.tsx index fa7690e9eeaff..0d5b379a62d38 100644 --- a/x-pack/plugins/security_solution/public/network/components/network_dns_table/index.tsx +++ b/x-pack/plugins/security_solution/public/network/components/network_dns_table/index.tsx @@ -5,7 +5,7 @@ */ import React, { useCallback, useMemo } from 'react'; -import { useDispatch, useSelector, shallowEqual } from 'react-redux'; +import { useDispatch } from 'react-redux'; import deepEqual from 'fast-deep-equal'; import { networkActions, networkModel, networkSelectors } from '../../store'; @@ -16,6 +16,7 @@ import { NetworkDnsFields, } from '../../../../common/search_strategy'; import { Criteria, ItemsPerRow, PaginatedTable } from '../../../common/components/paginated_table'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { getNetworkDnsColumns } from './columns'; import { IsPtrIncluded } from './is_ptr_included'; @@ -59,10 +60,7 @@ const NetworkDnsTableComponent: React.FC = ({ }) => { const dispatch = useDispatch(); const getNetworkDnsSelector = networkSelectors.dnsSelector(); - const { activePage, isPtrIncluded, limit, sort } = useSelector( - getNetworkDnsSelector, - shallowEqual - ); + const { activePage, isPtrIncluded, limit, sort } = useShallowEqualSelector(getNetworkDnsSelector); const updateLimitPagination = useCallback( (newLimit) => dispatch( diff --git a/x-pack/plugins/security_solution/public/network/components/network_http_table/index.tsx b/x-pack/plugins/security_solution/public/network/components/network_http_table/index.tsx index ccb238bcee274..6982388cafd9c 100644 --- a/x-pack/plugins/security_solution/public/network/components/network_http_table/index.tsx +++ b/x-pack/plugins/security_solution/public/network/components/network_http_table/index.tsx @@ -5,11 +5,11 @@ */ import React, { useCallback, useMemo } from 'react'; -import { useDispatch, useSelector, shallowEqual } from 'react-redux'; +import { useDispatch } from 'react-redux'; import { networkActions, networkModel, networkSelectors } from '../../store'; import { NetworkHttpEdges, NetworkHttpFields } from '../../../../common/search_strategy'; -import { State } from '../../../common/store'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { Criteria, ItemsPerRow, PaginatedTable } from '../../../common/components/paginated_table'; import { getNetworkHttpColumns } from './columns'; @@ -51,9 +51,8 @@ const NetworkHttpTableComponent: React.FC = ({ }) => { const dispatch = useDispatch(); const getNetworkHttpSelector = networkSelectors.httpSelector(); - const { activePage, limit, sort } = useSelector( - (state: State) => getNetworkHttpSelector(state, type), - shallowEqual + const { activePage, limit, sort } = useShallowEqualSelector((state) => + getNetworkHttpSelector(state, type) ); const tableType = type === networkModel.NetworkType.page diff --git a/x-pack/plugins/security_solution/public/network/components/network_top_countries_table/index.tsx b/x-pack/plugins/security_solution/public/network/components/network_top_countries_table/index.tsx index 2495f9e7c11c8..9b265aa002ccc 100644 --- a/x-pack/plugins/security_solution/public/network/components/network_top_countries_table/index.tsx +++ b/x-pack/plugins/security_solution/public/network/components/network_top_countries_table/index.tsx @@ -6,7 +6,7 @@ import { last } from 'lodash/fp'; import React, { useCallback, useMemo } from 'react'; -import { useDispatch, useSelector, shallowEqual } from 'react-redux'; +import { useDispatch } from 'react-redux'; import deepEqual from 'fast-deep-equal'; import { IIndexPattern } from 'src/plugins/data/public'; @@ -18,7 +18,7 @@ import { NetworkTopTablesFields, SortField, } from '../../../../common/search_strategy'; -import { State } from '../../../common/store'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { Criteria, ItemsPerRow, PaginatedTable } from '../../../common/components/paginated_table'; @@ -67,9 +67,8 @@ const NetworkTopCountriesTableComponent: React.FC }) => { const dispatch = useDispatch(); const getTopCountriesSelector = networkSelectors.topCountriesSelector(); - const { activePage, limit, sort } = useSelector( - (state: State) => getTopCountriesSelector(state, type, flowTargeted), - shallowEqual + const { activePage, limit, sort } = useShallowEqualSelector((state) => + getTopCountriesSelector(state, type, flowTargeted) ); const headerTitle: string = useMemo( diff --git a/x-pack/plugins/security_solution/public/network/components/network_top_n_flow_table/index.tsx b/x-pack/plugins/security_solution/public/network/components/network_top_n_flow_table/index.tsx index 9824ac602bb43..b1789569bed75 100644 --- a/x-pack/plugins/security_solution/public/network/components/network_top_n_flow_table/index.tsx +++ b/x-pack/plugins/security_solution/public/network/components/network_top_n_flow_table/index.tsx @@ -5,7 +5,7 @@ */ import { last } from 'lodash/fp'; import React, { useCallback, useMemo } from 'react'; -import { useDispatch, useSelector, shallowEqual } from 'react-redux'; +import { useDispatch } from 'react-redux'; import deepEqual from 'fast-deep-equal'; import { @@ -15,7 +15,7 @@ import { NetworkTopNFlowEdges, NetworkTopTablesFields, } from '../../../../common/search_strategy'; -import { State } from '../../../common/store'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { Criteria, ItemsPerRow, PaginatedTable } from '../../../common/components/paginated_table'; import { networkActions, networkModel, networkSelectors } from '../../store'; import { getNFlowColumnsCurated } from './columns'; @@ -61,9 +61,8 @@ const NetworkTopNFlowTableComponent: React.FC = ({ }) => { const dispatch = useDispatch(); const getTopNFlowSelector = networkSelectors.topNFlowSelector(); - const { activePage, limit, sort } = useSelector( - (state: State) => getTopNFlowSelector(state, type, flowTargeted), - shallowEqual + const { activePage, limit, sort } = useShallowEqualSelector((state) => + getTopNFlowSelector(state, type, flowTargeted) ); const columns = useMemo( diff --git a/x-pack/plugins/security_solution/public/network/components/tls_table/index.tsx b/x-pack/plugins/security_solution/public/network/components/tls_table/index.tsx index 3d19eedc06a8e..79590bdfa0870 100644 --- a/x-pack/plugins/security_solution/public/network/components/tls_table/index.tsx +++ b/x-pack/plugins/security_solution/public/network/components/tls_table/index.tsx @@ -5,7 +5,7 @@ */ import React, { useCallback, useMemo } from 'react'; -import { useDispatch, useSelector, shallowEqual } from 'react-redux'; +import { useDispatch } from 'react-redux'; import deepEqual from 'fast-deep-equal'; import { networkActions, networkModel, networkSelectors } from '../../store'; @@ -15,7 +15,7 @@ import { NetworkTlsFields, SortField, } from '../../../../common/search_strategy'; -import { State } from '../../../common/store'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { Criteria, ItemsPerRow, @@ -63,9 +63,8 @@ const TlsTableComponent: React.FC = ({ }) => { const dispatch = useDispatch(); const getTlsSelector = networkSelectors.tlsSelector(); - const { activePage, limit, sort } = useSelector( - (state: State) => getTlsSelector(state, type), - shallowEqual + const { activePage, limit, sort } = useShallowEqualSelector((state) => + getTlsSelector(state, type) ); const tableType: networkModel.TopTlsTableType = type === networkModel.NetworkType.page diff --git a/x-pack/plugins/security_solution/public/network/components/users_table/index.tsx b/x-pack/plugins/security_solution/public/network/components/users_table/index.tsx index 0355d0a30cfa4..7829449530829 100644 --- a/x-pack/plugins/security_solution/public/network/components/users_table/index.tsx +++ b/x-pack/plugins/security_solution/public/network/components/users_table/index.tsx @@ -5,9 +5,10 @@ */ import React, { useCallback, useMemo } from 'react'; -import { useDispatch, useSelector, shallowEqual } from 'react-redux'; +import { useDispatch } from 'react-redux'; import deepEqual from 'fast-deep-equal'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { assertUnreachable } from '../../../../common/utility_types'; import { networkActions, networkModel, networkSelectors } from '../../store'; import { @@ -68,7 +69,7 @@ const UsersTableComponent: React.FC = ({ }) => { const dispatch = useDispatch(); const getUsersSelector = networkSelectors.usersSelector(); - const { activePage, sort, limit } = useSelector(getUsersSelector, shallowEqual); + const { activePage, sort, limit } = useShallowEqualSelector(getUsersSelector); const updateLimitPagination = useCallback( (newLimit) => dispatch( diff --git a/x-pack/plugins/security_solution/public/network/containers/network_dns/index.tsx b/x-pack/plugins/security_solution/public/network/containers/network_dns/index.tsx index 1f199ba4f9acd..c49aa6a415904 100644 --- a/x-pack/plugins/security_solution/public/network/containers/network_dns/index.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/network_dns/index.tsx @@ -6,11 +6,11 @@ import { noop } from 'lodash/fp'; import { useState, useEffect, useCallback, useRef } from 'react'; -import { shallowEqual, useSelector } from 'react-redux'; import deepEqual from 'fast-deep-equal'; import { ESTermQuery } from '../../../../common/typed_json'; -import { inputsModel, State } from '../../../common/store'; +import { inputsModel } from '../../../common/store'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { useKibana } from '../../../common/lib/kibana'; import { createFilter } from '../../../common/containers/helpers'; import { NetworkDnsEdges, PageInfoPaginated } from '../../../../common/search_strategy'; @@ -68,10 +68,7 @@ export const useNetworkDns = ({ type, }: UseNetworkDns): [boolean, NetworkDnsArgs] => { const getNetworkDnsSelector = networkSelectors.dnsSelector(); - const { activePage, sort, isPtrIncluded, limit } = useSelector( - (state: State) => getNetworkDnsSelector(state), - shallowEqual - ); + const { activePage, sort, isPtrIncluded, limit } = useShallowEqualSelector(getNetworkDnsSelector); const { data, notifications } = useKibana().services; const refetch = useRef(noop); const abortCtrl = useRef(new AbortController()); diff --git a/x-pack/plugins/security_solution/public/network/containers/network_http/index.tsx b/x-pack/plugins/security_solution/public/network/containers/network_http/index.tsx index 98202f6b42be6..ec4ac39599351 100644 --- a/x-pack/plugins/security_solution/public/network/containers/network_http/index.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/network_http/index.tsx @@ -6,11 +6,11 @@ import { noop } from 'lodash/fp'; import { useState, useEffect, useCallback, useRef } from 'react'; -import { shallowEqual, useSelector } from 'react-redux'; import deepEqual from 'fast-deep-equal'; import { ESTermQuery } from '../../../../common/typed_json'; -import { inputsModel, State } from '../../../common/store'; +import { inputsModel } from '../../../common/store'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { useKibana } from '../../../common/lib/kibana'; import { createFilter } from '../../../common/containers/helpers'; import { generateTablePaginationOptions } from '../../../common/components/paginated_table/helpers'; @@ -68,9 +68,8 @@ export const useNetworkHttp = ({ type, }: UseNetworkHttp): [boolean, NetworkHttpArgs] => { const getHttpSelector = networkSelectors.httpSelector(); - const { activePage, limit, sort } = useSelector( - (state: State) => getHttpSelector(state, type), - shallowEqual + const { activePage, limit, sort } = useShallowEqualSelector((state) => + getHttpSelector(state, type) ); const { data, notifications } = useKibana().services; const refetch = useRef(noop); diff --git a/x-pack/plugins/security_solution/public/network/containers/network_top_countries/index.tsx b/x-pack/plugins/security_solution/public/network/containers/network_top_countries/index.tsx index 6b52966342e97..2d75de138a88c 100644 --- a/x-pack/plugins/security_solution/public/network/containers/network_top_countries/index.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/network_top_countries/index.tsx @@ -6,11 +6,11 @@ import { noop } from 'lodash/fp'; import { useState, useEffect, useCallback, useRef } from 'react'; -import { shallowEqual, useSelector } from 'react-redux'; import deepEqual from 'fast-deep-equal'; import { ESTermQuery } from '../../../../common/typed_json'; -import { inputsModel, State } from '../../../common/store'; +import { inputsModel } from '../../../common/store'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { useKibana } from '../../../common/lib/kibana'; import { createFilter } from '../../../common/containers/helpers'; import { generateTablePaginationOptions } from '../../../common/components/paginated_table/helpers'; @@ -66,9 +66,8 @@ export const useNetworkTopCountries = ({ type, }: UseNetworkTopCountries): [boolean, NetworkTopCountriesArgs] => { const getTopCountriesSelector = networkSelectors.topCountriesSelector(); - const { activePage, limit, sort } = useSelector( - (state: State) => getTopCountriesSelector(state, type, flowTarget), - shallowEqual + const { activePage, limit, sort } = useShallowEqualSelector((state) => + getTopCountriesSelector(state, type, flowTarget) ); const { data, notifications } = useKibana().services; const refetch = useRef(noop); diff --git a/x-pack/plugins/security_solution/public/network/containers/network_top_n_flow/index.tsx b/x-pack/plugins/security_solution/public/network/containers/network_top_n_flow/index.tsx index d6dd14b3259f0..328bb5aabcbb8 100644 --- a/x-pack/plugins/security_solution/public/network/containers/network_top_n_flow/index.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/network_top_n_flow/index.tsx @@ -6,11 +6,11 @@ import { noop } from 'lodash/fp'; import { useState, useEffect, useCallback, useRef } from 'react'; -import { shallowEqual, useSelector } from 'react-redux'; import deepEqual from 'fast-deep-equal'; import { ESTermQuery } from '../../../../common/typed_json'; -import { inputsModel, State } from '../../../common/store'; +import { inputsModel } from '../../../common/store'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { useKibana } from '../../../common/lib/kibana'; import { createFilter } from '../../../common/containers/helpers'; import { generateTablePaginationOptions } from '../../../common/components/paginated_table/helpers'; @@ -66,9 +66,8 @@ export const useNetworkTopNFlow = ({ type, }: UseNetworkTopNFlow): [boolean, NetworkTopNFlowArgs] => { const getTopNFlowSelector = networkSelectors.topNFlowSelector(); - const { activePage, limit, sort } = useSelector( - (state: State) => getTopNFlowSelector(state, type, flowTarget), - shallowEqual + const { activePage, limit, sort } = useShallowEqualSelector((state) => + getTopNFlowSelector(state, type, flowTarget) ); const { data, notifications } = useKibana().services; const refetch = useRef(noop); diff --git a/x-pack/plugins/security_solution/public/network/containers/tls/index.tsx b/x-pack/plugins/security_solution/public/network/containers/tls/index.tsx index f40675a1255ff..ddea2914a1bbb 100644 --- a/x-pack/plugins/security_solution/public/network/containers/tls/index.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/tls/index.tsx @@ -6,11 +6,11 @@ import { noop } from 'lodash/fp'; import { useState, useEffect, useCallback, useRef } from 'react'; -import { shallowEqual, useSelector } from 'react-redux'; import deepEqual from 'fast-deep-equal'; import { ESTermQuery } from '../../../../common/typed_json'; -import { inputsModel, State } from '../../../common/store'; +import { inputsModel } from '../../../common/store'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { useKibana } from '../../../common/lib/kibana'; import { createFilter } from '../../../common/containers/helpers'; import { PageInfoPaginated, FlowTargetSourceDest } from '../../../graphql/types'; @@ -67,9 +67,8 @@ export const useNetworkTls = ({ type, }: UseNetworkTls): [boolean, NetworkTlsArgs] => { const getTlsSelector = networkSelectors.tlsSelector(); - const { activePage, limit, sort } = useSelector( - (state: State) => getTlsSelector(state, type, flowTarget), - shallowEqual + const { activePage, limit, sort } = useShallowEqualSelector((state) => + getTlsSelector(state, type, flowTarget) ); const { data, notifications } = useKibana().services; const refetch = useRef(noop); diff --git a/x-pack/plugins/security_solution/public/network/containers/users/index.tsx b/x-pack/plugins/security_solution/public/network/containers/users/index.tsx index a289f8d16e9b2..5bca8d773c2f6 100644 --- a/x-pack/plugins/security_solution/public/network/containers/users/index.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/users/index.tsx @@ -6,9 +6,9 @@ import { noop } from 'lodash/fp'; import { useState, useEffect, useCallback, useRef } from 'react'; -import { shallowEqual, useSelector } from 'react-redux'; import deepEqual from 'fast-deep-equal'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { ESTermQuery } from '../../../../common/typed_json'; import { DEFAULT_INDEX_KEY } from '../../../../common/constants'; import { inputsModel } from '../../../common/store'; @@ -66,7 +66,7 @@ export const useNetworkUsers = ({ startDate, }: UseNetworkUsers): [boolean, NetworkUsersArgs] => { const getNetworkUsersSelector = networkSelectors.usersSelector(); - const { activePage, sort, limit } = useSelector(getNetworkUsersSelector, shallowEqual); + const { activePage, sort, limit } = useShallowEqualSelector(getNetworkUsersSelector); const { data, notifications, uiSettings } = useKibana().services; const refetch = useRef(noop); const abortCtrl = useRef(new AbortController()); diff --git a/x-pack/plugins/security_solution/public/network/pages/details/index.tsx b/x-pack/plugins/security_solution/public/network/pages/details/index.tsx index a227dec410915..bd563c2bd7617 100644 --- a/x-pack/plugins/security_solution/public/network/pages/details/index.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/details/index.tsx @@ -6,9 +6,10 @@ import { EuiHorizontalRule, EuiSpacer, EuiFlexItem } from '@elastic/eui'; import React, { useCallback, useEffect, useMemo } from 'react'; -import { useDispatch, useSelector, shallowEqual } from 'react-redux'; +import { useDispatch } from 'react-redux'; import { useParams } from 'react-router-dom'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { FlowTarget, LastEventIndexKey } from '../../../../common/search_strategy'; import { useGlobalTime } from '../../../common/containers/use_global_time'; import { FiltersGlobal } from '../../../common/components/filters_global'; @@ -58,8 +59,8 @@ const NetworkDetailsComponent: React.FC = () => { const getGlobalQuerySelector = inputsSelectors.globalQuerySelector(); const getGlobalFiltersQuerySelector = inputsSelectors.globalFiltersQuerySelector(); - const query = useSelector(getGlobalQuerySelector, shallowEqual); - const filters = useSelector(getGlobalFiltersQuerySelector, shallowEqual); + const query = useShallowEqualSelector(getGlobalQuerySelector); + const filters = useShallowEqualSelector(getGlobalFiltersQuerySelector); const type = networkModel.NetworkType.details; const narrowDateRange = useCallback( diff --git a/x-pack/plugins/security_solution/public/timelines/components/graph_overlay/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/graph_overlay/index.tsx index dc9557da70f91..7b229b3fbb17e 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/graph_overlay/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/graph_overlay/index.tsx @@ -14,7 +14,7 @@ import { } from '@elastic/eui'; import { noop } from 'lodash/fp'; import React, { useCallback, useMemo } from 'react'; -import { connect, ConnectedProps, useDispatch, useSelector } from 'react-redux'; +import { connect, ConnectedProps, useDispatch } from 'react-redux'; import styled from 'styled-components'; import { FULL_SCREEN } from '../timeline/body/column_headers/translations'; @@ -22,6 +22,7 @@ import { EXIT_FULL_SCREEN } from '../../../common/components/exit_full_screen/tr import { DEFAULT_INDEX_KEY, FULL_SCREEN_TOGGLED_CLASS_NAME } from '../../../../common/constants'; import { useFullScreen } from '../../../common/containers/use_full_screen'; import { State } from '../../../common/store'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { TimelineId, TimelineType } from '../../../../common/types/timeline'; import { timelineSelectors } from '../../store/timeline'; import { timelineDefaults } from '../../store/timeline/defaults'; @@ -109,7 +110,7 @@ const GraphOverlayComponent = ({ dispatch(updateTimelineGraphEventId({ id: timelineId, graphEventId: '' })); }, [dispatch, timelineId]); - const currentTimeline = useSelector((state: State) => + const currentTimeline = useShallowEqualSelector((state) => timelineSelectors.selectTimeline(state, timelineId) ); diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.tsx index dc824a8eb6272..9498033ce2db3 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.tsx @@ -6,11 +6,12 @@ import ApolloClient from 'apollo-client'; import React, { useEffect, useState, useCallback, useMemo } from 'react'; -import { connect, ConnectedProps, shallowEqual, useSelector } from 'react-redux'; +import { connect, ConnectedProps } from 'react-redux'; import { Dispatch } from 'redux'; import { DeleteTimelineMutation, SortFieldTimeline, Direction } from '../../../graphql/types'; import { sourcererSelectors, State } from '../../../common/store'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { TimelineId } from '../../../../common/types/timeline'; import { ColumnHeaderOptions, TimelineModel } from '../../../timelines/store/timeline/model'; import { timelineSelectors } from '../../../timelines/store/timeline'; @@ -114,10 +115,7 @@ export const StatefulOpenTimelineComponent = React.memo( () => sourcererSelectors.getAllExistingIndexNamesSelector(), [] ); - const existingIndexNames = useSelector( - existingIndexNamesSelector, - shallowEqual - ); + const existingIndexNames = useShallowEqualSelector(existingIndexNamesSelector); const { customTemplateTimelineCount, diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/index.tsx index d01e8634a489f..3c3ec1689b244 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/index.tsx @@ -20,10 +20,11 @@ import { EuiInMemoryTable, } from '@elastic/eui'; import React, { useState, useCallback, useRef } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import styled from 'styled-components'; import { State } from '../../../common/store'; +import { useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { renderers } from './catalog'; import { setExcludedRowRendererIds as dispatchSetExcludedRowRendererIds } from '../../../timelines/store/timeline/actions'; @@ -81,7 +82,7 @@ const StatefulRowRenderersBrowserComponent: React.FC { const tableRef = useRef>(); const dispatch = useDispatch(); - const excludedRowRendererIds = useSelector( + const excludedRowRendererIds = useShallowEqualSelector( (state: State) => state.timeline.timelineById[timelineId]?.excludedRowRendererIds || [] ); const [show, setShow] = useState(false); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/actions/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/actions/index.test.tsx index fb1709df01320..0afca36309659 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/actions/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/actions/index.test.tsx @@ -5,22 +5,20 @@ */ import { mount } from 'enzyme'; import React from 'react'; -import { useSelector } from 'react-redux'; import { TestProviders, mockTimelineModel } from '../../../../../common/mock'; import { DEFAULT_ACTIONS_COLUMN_WIDTH } from '../constants'; import { Actions } from '.'; +import { useShallowEqualSelector } from '../../../../../common/hooks/use_selector'; -jest.mock('react-redux', () => { - const origin = jest.requireActual('react-redux'); - return { - ...origin, - useSelector: jest.fn(), - }; -}); +jest.mock('../../../../../common/hooks/use_selector', () => ({ + useShallowEqualSelector: jest.fn(), +})); describe('Actions', () => { - (useSelector as jest.Mock).mockReturnValue(mockTimelineModel); + beforeEach(() => { + (useShallowEqualSelector as jest.Mock).mockReturnValue(mockTimelineModel); + }); test('it renders a checkbox for selecting the event when `showCheckboxes` is `true`', () => { const wrapper = mount( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/event_column_view.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/event_column_view.tsx index 2c84a786d4432..f602ea1452e14 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/event_column_view.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/event_column_view.tsx @@ -6,8 +6,8 @@ import React, { useCallback, useMemo } from 'react'; import uuid from 'uuid'; -import { useSelector, shallowEqual } from 'react-redux'; +import { useShallowEqualSelector } from '../../../../../common/hooks/use_selector'; import { Ecs } from '../../../../../../common/ecs'; import { TimelineNonEcsData } from '../../../../../../common/search_strategy/timeline'; import { Note } from '../../../../../common/lib/note'; @@ -28,7 +28,6 @@ import { AlertContextMenu } from '../../../../../detections/components/alerts_ta import { InvestigateInTimelineAction } from '../../../../../detections/components/alerts_table/timeline_actions/investigate_in_timeline_action'; import { AddEventNoteAction } from '../actions/add_note_icon_item'; import { PinEventAction } from '../actions/pin_event_action'; -import { StoreState } from '../../../../../common/store/types'; import { inputsModel } from '../../../../../common/store'; import { TimelineId } from '../../../../../../common/types/timeline'; @@ -96,9 +95,8 @@ export const EventColumnView = React.memo( toggleShowNotes, updateNote, }) => { - const { timelineType, status } = useSelector( - (state) => state.timeline.timelineById[timelineId], - shallowEqual + const { timelineType, status } = useShallowEqualSelector( + (state) => state.timeline.timelineById[timelineId] ); const handlePinClicked = useCallback( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx index d8cc8ddd2f15a..d71af86c80247 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx @@ -5,11 +5,11 @@ */ import React, { useRef, useState, useCallback } from 'react'; -import { useSelector } from 'react-redux'; import uuid from 'uuid'; import VisibilitySensor from 'react-visibility-sensor'; import { BrowserFields, DocValueFields } from '../../../../../common/containers/source'; +import { useShallowEqualSelector } from '../../../../../common/hooks/use_selector'; import { useTimelineEventsDetails } from '../../../../containers/details'; import { TimelineEventsDetailsItem, @@ -37,7 +37,7 @@ import { getEventType } from '../helpers'; import { NoteCards } from '../../../notes/note_cards'; import { useEventDetailsWidthContext } from '../../../../../common/components/events_viewer/event_details_width_context'; import { EventColumnView } from './event_column_view'; -import { inputsModel, StoreState } from '../../../../../common/store'; +import { inputsModel } from '../../../../../common/store'; interface Props { actionsColumnWidth: number; @@ -136,7 +136,7 @@ const StatefulEventComponent: React.FC = ({ }) => { const [expanded, setExpanded] = useState<{ [eventId: string]: boolean }>({}); const [showNotes, setShowNotes] = useState<{ [eventId: string]: boolean }>({}); - const { status: timelineStatus } = useSelector( + const { status: timelineStatus } = useShallowEqualSelector( (state) => state.timeline.timelineById[timelineId] ); const divElement = useRef(null); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx index 23a449cca972d..8b859c1746a46 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx @@ -5,7 +5,6 @@ */ import { ReactWrapper } from 'enzyme'; import React from 'react'; -import { useSelector } from 'react-redux'; import '../../../../common/mock/match_media'; import { mockBrowserFields } from '../../../../common/containers/source/mock'; @@ -28,13 +27,9 @@ const mockSort: Sort = { sortDirection: Direction.desc, }; -jest.mock('react-redux', () => { - const origin = jest.requireActual('react-redux'); - return { - ...origin, - useSelector: jest.fn(), - }; -}); +jest.mock('../../../../common/hooks/use_selector', () => ({ + useShallowEqualSelector: jest.fn().mockReturnValue(mockTimelineModel), +})); jest.mock('../../../../common/components/link_to'); @@ -87,7 +82,6 @@ describe('Body', () => { toggleColumn: jest.fn(), updateNote: jest.fn(), }; - (useSelector as jest.Mock).mockReturnValue(mockTimelineModel); describe('rendering', () => { test('it renders the column headers', () => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/add_data_provider_popover.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/add_data_provider_popover.tsx index 1bfeb482873c7..3523e8c0d7aaf 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/add_data_provider_popover.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/add_data_provider_popover.tsx @@ -15,10 +15,11 @@ import { EuiContextMenuPanelItemDescriptor, } from '@elastic/eui'; import uuid from 'uuid'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import { BrowserFields } from '../../../../common/containers/source'; import { TimelineType } from '../../../../../common/types/timeline'; +import { useShallowEqualSelector } from '../../../../common/hooks/use_selector'; import { StatefulEditDataProvider } from '../../edit_data_provider'; import { addContentToTimeline } from './helpers'; import { DataProviderType } from './data_provider'; @@ -36,7 +37,7 @@ const AddDataProviderPopoverComponent: React.FC = ( }) => { const dispatch = useDispatch(); const [isAddFilterPopoverOpen, setIsAddFilterPopoverOpen] = useState(false); - const timelineById = useSelector(timelineSelectors.timelineByIdSelector); + const timelineById = useShallowEqualSelector(timelineSelectors.timelineByIdSelector); const { dataProviders, timelineType } = timelineById[timelineId] ?? {}; const handleOpenPopover = useCallback(() => setIsAddFilterPopoverOpen(true), [ diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_badge.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_badge.tsx index ece23d7a10886..0093c43a17137 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_badge.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_badge.tsx @@ -6,10 +6,11 @@ import { noop } from 'lodash/fp'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import { TimelineType } from '../../../../../common/types/timeline'; import { BrowserFields } from '../../../../common/containers/source'; +import { useShallowEqualSelector } from '../../../../common/hooks/use_selector'; import { timelineSelectors } from '../../../store/timeline'; import { OnDataProviderEdited } from '../events'; @@ -59,7 +60,7 @@ export const ProviderItemBadge = React.memo( val, type = DataProviderType.default, }) => { - const timelineById = useSelector(timelineSelectors.timelineByIdSelector); + const timelineById = useShallowEqualSelector(timelineSelectors.timelineByIdSelector); const timelineType = timelineId ? timelineById[timelineId]?.timelineType : TimelineType.default; const { getManageTimelineById } = useManageTimeline(); const isLoading = useMemo(() => getManageTimelineById(timelineId ?? '').isLoading, [ diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/insert_timeline_popover/use_insert_timeline.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/insert_timeline_popover/use_insert_timeline.tsx index f1f419fd4b52a..6a65819a764eb 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/insert_timeline_popover/use_insert_timeline.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/insert_timeline_popover/use_insert_timeline.tsx @@ -5,7 +5,9 @@ */ import { useCallback, useState, useEffect } from 'react'; -import { useDispatch, useSelector, shallowEqual } from 'react-redux'; +import { useDispatch } from 'react-redux'; + +import { useShallowEqualSelector } from '../../../../common/hooks/use_selector'; import { SecurityPageName } from '../../../../../common/constants'; import { getTimelineUrl, useFormatUrl } from '../../../../common/components/link_to'; import { CursorPosition } from '../../../../common/components/markdown_editor'; @@ -20,7 +22,7 @@ export const useInsertTimeline = (value: string, onChange: (newValue: string) => end: 0, }); - const insertTimeline = useSelector(timelineSelectors.selectInsertTimeline, shallowEqual); + const insertTimeline = useShallowEqualSelector(timelineSelectors.selectInsertTimeline); const handleOnTimelineChange = useCallback( (title: string, id: string | null, graphEventId?: string) => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/helpers.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/helpers.tsx index 0f6535015c799..43ab8ab203e11 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/helpers.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/helpers.tsx @@ -20,7 +20,7 @@ import { import React, { useCallback, useMemo } from 'react'; import uuid from 'uuid'; import styled from 'styled-components'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import { APP_ID } from '../../../../../common/constants'; import { @@ -33,9 +33,9 @@ import { import { SecurityPageName } from '../../../../app/types'; import { timelineSelectors } from '../../../../timelines/store/timeline'; import { getCreateCaseUrl } from '../../../../common/components/link_to'; -import { State } from '../../../../common/store'; import { useKibana } from '../../../../common/lib/kibana'; import { Note } from '../../../../common/lib/note'; +import { useShallowEqualSelector } from '../../../../common/hooks/use_selector'; import { Notes } from '../../notes'; import { AssociateNote, UpdateNote } from '../../notes/helpers'; @@ -159,7 +159,7 @@ interface NewCaseProps { export const NewCase = React.memo( ({ compact, graphEventId, onClosePopover, timelineId, timelineStatus, timelineTitle }) => { const dispatch = useDispatch(); - const { savedObjectId } = useSelector((state: State) => + const { savedObjectId } = useShallowEqualSelector((state) => timelineSelectors.selectTimeline(state, timelineId) ); const { navigateToApp } = useKibana().services.application; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/use_create_timeline.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/use_create_timeline.tsx index 3919ee21b2a90..28dd865c763ae 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/use_create_timeline.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/use_create_timeline.tsx @@ -4,8 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ import React, { useCallback, useMemo } from 'react'; -import { shallowEqual, useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import { EuiButton, EuiButtonEmpty } from '@elastic/eui'; + import { defaultHeaders } from '../body/column_headers/default_headers'; import { timelineActions } from '../../../store/timeline'; import { useFullScreen } from '../../../../common/containers/use_full_screen'; @@ -14,9 +15,9 @@ import { TimelineType, TimelineTypeLiteral, } from '../../../../../common/types/timeline'; +import { useShallowEqualSelector } from '../../../../common/hooks/use_selector'; import { inputsActions, inputsSelectors } from '../../../../common/store/inputs'; import { sourcererActions, sourcererSelectors } from '../../../../common/store/sourcerer'; -import { State } from '../../../../common/store'; import { SourcererScopeName } from '../../../../common/store/sourcerer/model'; export const useCreateTimelineButton = ({ @@ -33,9 +34,9 @@ export const useCreateTimelineButton = ({ () => sourcererSelectors.getAllExistingIndexNamesSelector(), [] ); - const existingIndexNames = useSelector(existingIndexNamesSelector, shallowEqual); + const existingIndexNames = useShallowEqualSelector(existingIndexNamesSelector); const { timelineFullScreen, setTimelineFullScreen } = useFullScreen(); - const globalTimeRange = useSelector(inputsSelectors.globalTimeRangeSelector); + const globalTimeRange = useShallowEqualSelector(inputsSelectors.globalTimeRangeSelector); const createTimeline = useCallback( ({ id, show }) => { if (id === TimelineId.active && timelineFullScreen) {