diff --git a/lib/keyserver-conn/call-keyserver-endpoint-provider.react.js b/lib/keyserver-conn/call-keyserver-endpoint-provider.react.js --- a/lib/keyserver-conn/call-keyserver-endpoint-provider.react.js +++ b/lib/keyserver-conn/call-keyserver-endpoint-provider.react.js @@ -22,14 +22,14 @@ import callServerEndpoint from '../utils/call-server-endpoint.js'; export type ActionFunc = (callServerEndpoint: CallServerEndpoint) => F; -type CreateBoundServerCallsSelectorType = ( +type CreateCallSingleKeyserverEndpointSelector = ( keyserverID: string, -) => (ActionFunc) => ServerCallSelectorParams => F; +) => ServerCallSelectorParams => CallServerEndpoint; type CallKeyserverEndpointContextType = { +bindCookieAndUtilsIntoCallServerEndpoint: ( params: BindServerCallsParams, ) => CallServerEndpoint, - +createBoundServerCallsSelector: CreateBoundServerCallsSelectorType, + +createCallSingleKeyserverEndpointSelector: CreateCallSingleKeyserverEndpointSelector, }; const CallKeyserverEndpointContext: React.Context = @@ -191,61 +191,54 @@ ); }, []); - // All server calls needs to include some information from the Redux state - // (namely, the cookie). This information is used deep in the server call, - // at the point where callServerEndpoint is called. We don't want to bother - // propagating the cookie (and any future config info that callServerEndpoint - // needs) through to the server calls so they can pass it to - // callServerEndpoint. Instead, we "curry" the cookie onto callServerEndpoint - // within react-redux's connect's mapStateToProps function, and then pass that - // "bound" callServerEndpoint that no longer needs the cookie as a parameter - // on to the server call. - const createBoundServerCallsSelector = React.useCallback( - ( - keyserverID: string, - ): ((actionFunc: ActionFunc) => ServerCallSelectorParams => F) => - actionFunc => - createSelector( - (state: ServerCallSelectorParams) => state.dispatch, - (state: ServerCallSelectorParams) => state.cookie, - (state: ServerCallSelectorParams) => state.urlPrefix, - (state: ServerCallSelectorParams) => state.sessionID, - (state: ServerCallSelectorParams) => state.currentUserInfo, - (state: ServerCallSelectorParams) => state.isSocketConnected, - (state: ServerCallSelectorParams) => - state.lastCommunicatedPlatformDetails, - ( - dispatch: Dispatch, - cookie: ?string, - urlPrefix: string, - sessionID: ?string, - currentUserInfo: ?CurrentUserInfo, - isSocketConnected: boolean, - lastCommunicatedPlatformDetails: ?PlatformDetails, - ) => { - const boundCallServerEndpoint = - bindCookieAndUtilsIntoCallServerEndpoint({ - dispatch, - cookie, - urlPrefix, - sessionID, - currentUserInfo, - isSocketConnected, - lastCommunicatedPlatformDetails, - keyserverID, - }); - return actionFunc(boundCallServerEndpoint); - }, - ), + // For each keyserver, we have a set of params that configure our connection + // to it. These params get bound into callServerEndpoint before it's passed to + // an ActionFunc. This helper function lets us create a selector for a given + // keyserverID that will regenerate the bound callServerEndpoint function only + // if one of the params changes. This lets us skip some React render cycles. + const createCallSingleKeyserverEndpointSelector = React.useCallback( + (keyserverID: string): (ServerCallSelectorParams => CallServerEndpoint) => + createSelector( + (params: ServerCallSelectorParams) => params.dispatch, + (params: ServerCallSelectorParams) => params.cookie, + (params: ServerCallSelectorParams) => params.urlPrefix, + (params: ServerCallSelectorParams) => params.sessionID, + (params: ServerCallSelectorParams) => params.currentUserInfo, + (params: ServerCallSelectorParams) => params.isSocketConnected, + (params: ServerCallSelectorParams) => + params.lastCommunicatedPlatformDetails, + ( + dispatch: Dispatch, + cookie: ?string, + urlPrefix: string, + sessionID: ?string, + currentUserInfo: ?CurrentUserInfo, + isSocketConnected: boolean, + lastCommunicatedPlatformDetails: ?PlatformDetails, + ) => + bindCookieAndUtilsIntoCallServerEndpoint({ + dispatch, + cookie, + urlPrefix, + sessionID, + currentUserInfo, + isSocketConnected, + lastCommunicatedPlatformDetails, + keyserverID, + }), + ), [bindCookieAndUtilsIntoCallServerEndpoint], ); const value = React.useMemo( () => ({ bindCookieAndUtilsIntoCallServerEndpoint, - createBoundServerCallsSelector, + createCallSingleKeyserverEndpointSelector, }), - [bindCookieAndUtilsIntoCallServerEndpoint, createBoundServerCallsSelector], + [ + bindCookieAndUtilsIntoCallServerEndpoint, + createCallSingleKeyserverEndpointSelector, + ], ); return ( diff --git a/lib/utils/action-utils.js b/lib/utils/action-utils.js --- a/lib/utils/action-utils.js +++ b/lib/utils/action-utils.js @@ -20,10 +20,11 @@ const serverCallState = useSelector( serverCallStateSelector(ashoatKeyserverID), ); - const { createBoundServerCallsSelector } = useCallKeyserverEndpointContext(); + const { createCallSingleKeyserverEndpointSelector } = + useCallKeyserverEndpointContext(); const selector = React.useMemo( - () => createBoundServerCallsSelector(ashoatKeyserverID)(serverCall), - [createBoundServerCallsSelector, serverCall], + () => createCallSingleKeyserverEndpointSelector(ashoatKeyserverID), + [createCallSingleKeyserverEndpointSelector], ); return React.useMemo(() => { @@ -35,14 +36,15 @@ 'keyserver missing from keyserverStore', ); - return selector({ + const callServerEndpoint = selector({ ...serverCallState, urlPrefix, isSocketConnected, dispatch, ...paramOverride, }); - }, [serverCallState, dispatch, paramOverride, selector]); + return serverCall(callServerEndpoint); + }, [serverCall, serverCallState, dispatch, paramOverride, selector]); } export { useServerCall };