Repository: tannerlinsley/react-query
Pull request #774 (2020-07-17 18:04:30)

feat(queryCache): merge defaultConfig options
Providing a `defaultConfig` to `makeQueryCache` will merge `shared`, `queries`, and `mutations`
objects instead of overwriting. This allows you to configure only some options.

vercel[bot]: 
This pull request is being automatically deployed with Vercel ([learn more](https://vercel.link/github-learn-more)).
To see the status of your deployment, click on the icon next to each commit.
	

Patch:
diff --git a/docs/src/components/Nav.js b/docs/src/components/Nav.js
index ed8b72750..56cc745cd 100644
--- a/docs/src/components/Nav.js
+++ b/docs/src/components/Nav.js
@@ -2,21 +2,27 @@ import * as React from 'react'
 import Link from 'next/link'
 import logoSrc from '../images/logo.svg'
 import { siteConfig } from 'siteConfig'
+import { Search } from './Search'
 
 export const Nav = () => (
   <div className="bg-white border-b border-gray-200">
     <div className="container mx-auto">
-      <div className="grid grid-cols-1 md:grid-cols-12 md:gap-6">
-        <div className="w-60 col-span-3 flex items-center h-16 pt-4 md:pt-0">
+      <div className="flex flex-wrap items-center">
+        <div className="w-60 flex items-center h-16 pt-4 md:pt-0">
           <Link href="/" as="/">
             <a>
               <span className="sr-only">Home</span>
-              <img src={logoSrc} />
+              <img src={logoSrc} alt="React Query" />
             </a>
           </Link>
         </div>
-        <div className="md:col-span-9 items-center flex justify-between md:justify-end space-x-4 md:space-x-8 h-16">
-          <div className="flex items-center space-x-4 md:space-x-8 text-sm md:text-base">
+
+        <div className="flex-grow hidden lg:block ml-8">
+          <Search />
+        </div>
+
+        <div className="flex flex-grow items-center justify-between w-3/4 md:w-auto md:justify-end space-x-4 md:space-x-8 h-16">
+          <div className="flex space-x-4 md:space-x-8 text-sm md:text-base">
             <div>
               <Link href="/docs/overview">
                 <a className="leading-6 font-medium">Docs</a>
diff --git a/docs/src/components/Search.js b/docs/src/components/Search.js
index d2ea8ba66..7a89f7e60 100644
--- a/docs/src/components/Search.js
+++ b/docs/src/components/Search.js
@@ -1,104 +1,56 @@
-import * as React from 'react';
-import { createPortal } from 'react-dom';
-import Router from 'next/router';
-import Link from 'next/link';
-import Head from 'next/head';
-import { useDocSearchKeyboardEvents } from '@docsearch/react';
-import { siteConfig } from 'siteConfig';
+import * as React from 'react'
+import { useSearch } from './useSearch'
 
-function Hit({
-  hit,
-  children
-}) {
-  return <Link href={hit.url.replace()}>
-      <a>{children}</a>
-    </Link>;
-}
-
-const options = {
-  appId: siteConfig.algolia.appId,
-  apiKey: siteConfig.algolia.apiKey,
-  indexName: siteConfig.algolia.indexName,
-  rednerModal: true
-};
-let DocSearchModal = null;
-export const Search = ({
-  appId,
-  searchParameters = {
-    hitsPerPage: 5
-  },
-  renderModal = true
-}) => {
-  const [isLoaded, setIsLoaded] = React.useState(true);
-  const [isShowing, setIsShowing] = React.useState(false);
-  const scrollY = React.useRef(0);
-  const importDocSearchModalIfNeeded = React.useCallback(function importDocSearchModalIfNeeded() {
-    if (DocSearchModal) {
-      return Promise.resolve();
-    }
-
-    return Promise.all([import('@docsearch/react/modal')]).then(([{
-      DocSearchModal: Modal
-    }]) => {
-      DocSearchModal = Modal;
-    });
-  }, []);
-  const onOpen = React.useCallback(function onOpen() {
-    importDocSearchModalIfNeeded().then(() => {
-      setIsShowing(true);
-    });
-  }, [importDocSearchModalIfNeeded, setIsShowing]);
-  const onClose = React.useCallback(function onClose() {
-    setIsShowing(false);
-  }, [setIsShowing]);
-  useDocSearchKeyboardEvents({
-    isOpen: isShowing,
-    onOpen,
-    onClose
-  });
-  return <>
-      <Head>
-        <link rel="preconnect" href={`https://${appId}-dsn.algolia.net`} crossOrigin="true" />
-      </Head>
+export const Search = () => {
+  const { onOpen } = useSearch()
 
-      <div>
-        <button type="button" className="group form-input hover:text-gray-600 hover:border-gray-300 transition duration-150 ease-in-out pointer flex items-center bg-gray-50 text-left w-full  text-gray-500 rounded-lg text-sm align-middle" onClick={onOpen}>
-          <svg width="1em" height="1em" className="mr-3 align-middle text-gray-600 flex-shrink-0 group-hover:text-gray-700" style={{
-          marginBottom: 2
-        }} viewBox="0 0 20 20">
-            <path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" strokeWidth="2" fillRule="evenodd" strokeLinecap="round" strokeLinejoin="round"></path>
-          </svg>
-          Search docs
-          <span className="ml-auto invisible lg:visible">
-            <kbd className="border border-gray-300 mr-1 bg-gray-100 align-middle p-0 inline-flex justify-center items-center  text-xs text-center mr-0 rounded group-hover:border-gray-300 transition duration-150 ease-in-out " style={{
-            minWidth: '1.8em'
-          }}>
-              ⌘
-            </kbd>
-            <kbd className="border border-gray-300 bg-gray-100 align-middle p-0 inline-flex justify-center items-center  text-xs text-center ml-auto mr-0 rounded group-hover:border-gray-300 transition duration-150 ease-in-out " style={{
-            minWidth: '1.8em'
-          }}>
-              K
-            </kbd>
-          </span>
-        </button>
-      </div>
-
-      {isLoaded && isShowing && createPortal(<DocSearchModal {...options} searchParameters={searchParameters} onClose={onClose} navigator={{
-      navigate({
-        suggestionUrl
-      }) {
-        Router.push(suggestionUrl);
-      }
-
-    }} transformItems={items => {
-      return items.map(item => {
-        const url = new URL(item.url);
-        return { ...item,
-          url: item.url.replace(url.origin, '').replace('#__next', '').replace('/docs/#', '/docs/overview#')
-        };
-      });
-    }} hitComponent={Hit} />, document.body)}
-    </>;
-};
-Search.displayName = 'Search';
\ No newline at end of file
+  return (
+    <div>
+      <button
+        type="button"
+        className="group form-input hover:text-gray-600 hover:border-gray-300 transition duration-150 ease-in-out pointer flex items-center bg-gray-50 text-left w-full  text-gray-500 rounded-lg text-sm align-middle"
+        onClick={onOpen}
+      >
+        <svg
+          width="1em"
+          height="1em"
+          className="mr-3 align-middle text-gray-600 flex-shrink-0 group-hover:text-gray-700"
+          style={{
+            marginBottom: 2,
+          }}
+          viewBox="0 0 20 20"
+        >
+          <path
+            d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z"
+            stroke="currentColor"
+            fill="none"
+            strokeWidth="2"
+            fillRule="evenodd"
+            strokeLinecap="round"
+            strokeLinejoin="round"
+          ></path>
+        </svg>
+        Search docs
+        <span className="ml-auto invisible lg:visible">
+          <kbd
+            className="border border-gray-300 mr-1 bg-gray-100 align-middle p-0 inline-flex justify-center items-center  text-xs text-center mr-0 rounded group-hover:border-gray-300 transition duration-150 ease-in-out "
+            style={{
+              minWidth: '1.8em',
+            }}
+          >
+            ⌘
+          </kbd>
+          <kbd
+            className="border border-gray-300 bg-gray-100 align-middle p-0 inline-flex justify-center items-center  text-xs text-center ml-auto mr-0 rounded group-hover:border-gray-300 transition duration-150 ease-in-out "
+            style={{
+              minWidth: '1.8em',
+            }}
+          >
+            K
+          </kbd>
+        </span>
+      </button>
+    </div>
+  )
+}
+Search.displayName = 'Search'
diff --git a/docs/src/components/Sidebar.js b/docs/src/components/Sidebar.js
index 56b84a4e6..056d73d8c 100644
--- a/docs/src/components/Sidebar.js
+++ b/docs/src/components/Sidebar.js
@@ -1,20 +1,19 @@
-import { useState } from 'react';
-import cn from 'classnames';
-import { Search } from './Search';
-export const Sidebar = ({
-  active,
-  children,
-  fixed
-}) => {
-  const [searching, setSearching] = useState(false);
-  return <aside className={cn('sidebar bg-white top-24 flex-shrink-0 pr-2', {
-    active,
-    ['pb-0 flex flex-col z-1 sticky']: fixed,
-    fixed,
-    searching
-  })}>
-      <div className="sidebar-search my-2">
-        <Search renderModal={false} />
+import { useState } from 'react'
+import cn from 'classnames'
+import { Search } from './Search'
+export const Sidebar = ({ active, children, fixed }) => {
+  const [searching, setSearching] = useState(false)
+  return (
+    <aside
+      className={cn('sidebar bg-white top-24 flex-shrink-0 pr-2', {
+        active,
+        ['pb-0 flex flex-col z-1 sticky']: fixed,
+        fixed,
+        searching,
+      })}
+    >
+      <div className="sidebar-search my-2 lg:hidden">
+        <Search />
       </div>
       <div className="sidebar-content overflow-y-auto pb-4">{children}</div>
       <style jsx>{`
@@ -44,5 +43,6 @@ export const Sidebar = ({
           }
         }
       `}</style>
-    </aside>;
-};
\ No newline at end of file
+    </aside>
+  )
+}
diff --git a/docs/src/components/useSearch.js b/docs/src/components/useSearch.js
new file mode 100644
index 000000000..a57ee1f93
--- /dev/null
+++ b/docs/src/components/useSearch.js
@@ -0,0 +1,105 @@
+import React from 'react'
+import { createPortal } from 'react-dom'
+import Router from 'next/router'
+import Head from 'next/head'
+import Link from 'next/link'
+import { useDocSearchKeyboardEvents } from '@docsearch/react'
+import { siteConfig } from 'siteConfig'
+
+const SearchContext = React.createContext()
+let DocSearchModal = null
+
+export const useSearch = () => React.useContext(SearchContext)
+
+export function SearchProvider({
+  children,
+  searchParameters = {
+    hitsPerPage: 5,
+  },
+}) {
+  const [isShowing, setIsShowing] = React.useState(false)
+
+  const onOpen = React.useCallback(function onOpen() {
+    function importDocSearchModalIfNeeded() {
+      if (DocSearchModal) {
+        return Promise.resolve()
+      }
+
+      return import('@docsearch/react/modal').then(
+        ({ DocSearchModal: Modal }) => (DocSearchModal = Modal)
+      )
+    }
+
+    importDocSearchModalIfNeeded().then(() => {
+      setIsShowing(true)
+    })
+  }, [])
+
+  const onClose = React.useCallback(() => setIsShowing(false), [])
+
+  useDocSearchKeyboardEvents({
+    isOpen: isShowing,
+    onOpen,
+    onClose,
+  })
+
+  const options = {
+    appId: siteConfig.algolia.appId,
+    apiKey: siteConfig.algolia.apiKey,
+    indexName: siteConfig.algolia.indexName,
+    renderModal: true,
+  }
+
+  return (
+    <>
+      <Head>
+        <link
+          key="algolia"
+          rel="preconnect"
+          href={`https://${options.appId}-dsn.algolia.net`}
+          crossOrigin="true"
+        />
+      </Head>
+
+      <SearchContext.Provider value={{ DocSearchModal, onOpen }}>
+        {children}
+      </SearchContext.Provider>
+
+      {isShowing &&
+        createPortal(
+          <DocSearchModal
+            {...options}
+            searchParameters={searchParameters}
+            onClose={onClose}
+            navigator={{
+              navigate({ suggestionUrl }) {
+                Router.push(suggestionUrl)
+              },
+            }}
+            transformItems={items => {
+              return items.map(item => {
+                const url = new URL(item.url)
+                return {
+                  ...item,
+                  url: item.url
+                    .replace(url.origin, '')
+                    .replace('#__next', '')
+                    .replace('/docs/#', '/docs/overview#'),
+                }
+              })
+            }}
+            hitComponent={Hit}
+          />,
+          document.body
+        )}
+    </>
+  )
+}
+
+function Hit({ hit, children }) {
+  return (
+    <Link href={hit.url.replace()}>
+      <a>{children}</a>
+    </Link>
+  )
+}
diff --git a/docs/src/pages/_app.js b/docs/src/pages/_app.js
index 88969b25b..ac518fabc 100644
--- a/docs/src/pages/_app.js
+++ b/docs/src/pages/_app.js
@@ -2,6 +2,7 @@ import React from 'react'
 import '@docsearch/react/dist/style.css'
 import '../styles/index.css'
 import Head from 'next/head'
+import { SearchProvider } from 'components/useSearch'
 
 function loadScript(src, attrs = {}) {
   if (typeof document !== 'undefined') {
@@ -46,7 +47,9 @@ function MyApp({ Component, pageProps }) {
           }}
         />
       </Head>
-      <Component {...pageProps} />
+      <SearchProvider>
+        <Component {...pageProps} />
+      </SearchProvider>
     </>
   )
 }
diff --git a/docs/yarn.lock b/docs/yarn.lock
index 297e40e48..4c6de71cb 100644
--- a/docs/yarn.lock
+++ b/docs/yarn.lock
@@ -1471,14 +1471,6 @@
   resolved "https://registry.yarnpkg.com/@next/plugin-google-analytics/-/plugin-google-analytics-9.4.4.tgz#0dc2aef2f9b10d3ad302cf07d88ca652c22e9f11"
   integrity sha512-X+EFML99AnOkshiZYPZUrmTn6EY1+rc+9B8k9o23pMNqP6dDEzmMc+aG73uEX1+zZ6wiuZqnZYJPXd+qH0tzeQ==
 
-"@next/plugin-sentry@^9.4.4":
-  version "9.4.4"
-  resolved "https://registry.yarnpkg.com/@next/plugin-sentry/-/plugin-sentry-9.4.4.tgz#a4b2afb3c39c1c2032114755449717cee41fa7c8"
-  integrity sha512-wMY8Jh42wGuuCfAktYM/2jucyz3yMJu70u0Fta/xK27UXnA9514k8mNwEpGHEz5uD7UayofO1m0PCcPRcS6JXA==
-  dependencies:
-    "@sentry/browser" "5.7.1"
-    "@sentry/node" "5.7.1"
-
 "@next/react-dev-overlay@9.4.4":
   version "9.4.4"
   resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-9.4.4.tgz#4ae03ac839ff022b3ce5c695bd24b179d4ef459d"
@@ -1547,72 +1539,6 @@
   resolved "https://registry.yarnpkg.com/@reactions/component/-/component-2.0.2.tgz#40f8c1c2c37baabe57a0c944edb9310dc1ec6642"
   integrity sha1-QPjBwsN7qr5XoMlE7bkxDcHsZkI=
 
-"@sentry/browser@5.7.1":
-  version "5.7.1"
-  resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.7.1.tgz#1f8435e2a325d7a09f830065ebce40a2b3c708a4"
-  integrity sha512-K0x1XhsHS8PPdtlVOLrKZyYvi5Vexs9WApdd214bO6KaGF296gJvH1mG8XOY0+7aA5i2A7T3ttcaJNDYS49lzw==
-  dependencies:
-    "@sentry/core" "5.7.1"
-    "@sentry/types" "5.7.1"
-    "@sentry/utils" "5.7.1"
-    tslib "^1.9.3"
-
-"@sentry/core@5.7.1":
-  version "5.7.1"
-  resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.7.1.tgz#3eb2b7662cac68245931ee939ec809bf7a639d0e"
-  integrity sha512-AOn3k3uVWh2VyajcHbV9Ta4ieDIeLckfo7UMLM+CTk2kt7C89SayDGayJMSsIrsZlL4qxBoLB9QY4W2FgAGJrg==
-  dependencies:
-    "@sentry/hub" "5.7.1"
-    "@sentry/minimal" "5.7.1"
-    "@sentry/types" "5.7.1"
-    "@sentry/utils" "5.7.1"
-    tslib "^1.9.3"
-
-"@sentry/hub@5.7.1":
-  version "5.7.1"
-  resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.7.1.tgz#a52acd9fead7f3779d96e9965c6978aecc8b9cad"
-  integrity sha512-evGh323WR073WSBCg/RkhlUmCQyzU0xzBzCZPscvcoy5hd4SsLE6t9Zin+WACHB9JFsRQIDwNDn+D+pj3yKsig==
-  dependencies:
-    "@sentry/types" "5.7.1"
-    "@sentry/utils" "5.7.1"
-    tslib "^1.9.3"
-
-"@sentry/minimal@5.7.1":
-  version "5.7.1"
-  resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.7.1.tgz#56afc537737586929e25349765e37a367958c1e1"
-  integrity sha512-nS/Dg+jWAZtcxQW8wKbkkw4dYvF6uyY/vDiz/jFCaux0LX0uhgXAC9gMOJmgJ/tYBLJ64l0ca5LzpZa7BMJQ0g==
-  dependencies:
-    "@sentry/hub" "5.7.1"
-    "@sentry/types" "5.7.1"
-    tslib "^1.9.3"
-
-"@sentry/node@5.7.1":
-  version "5.7.1"
-  resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.7.1.tgz#94e2fbac94f6cc061be3bc14b22813536c59698d"
-  integrity sha512-hVM10asFStrOhYZzMqFM7V1lrHkr1ydc2n/SFG0ZmIQxfTjCVElyXV/BJASIdqadM1fFIvvtD/EfgkTcZmub1g==
-  dependencies:
-    "@sentry/core" "5.7.1"
-    "@sentry/hub" "5.7.1"
-    "@sentry/types" "5.7.1"
-    "@sentry/utils" "5.7.1"
-    cookie "^0.3.1"
-    https-proxy-agent "^3.0.0"
-    lru_map "^0.3.3"
-    tslib "^1.9.3"
-
-"@sentry/types@5.7.1":
-  version "5.7.1"
-  resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.7.1.tgz#4c4c1d4d891b6b8c2c3c7b367d306a8b1350f090"
-  integrity sha512-tbUnTYlSliXvnou5D4C8Zr+7/wJrHLbpYX1YkLXuIJRU0NSi81bHMroAuHWILcQKWhVjaV/HZzr7Y/hhWtbXVQ==
-
-"@sentry/utils@5.7.1":
-  version "5.7.1"
-  resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.7.1.tgz#cf37ad55f78e317665cd8680f202d307fa77f1d0"
-  integrity sha512-nhirUKj/qFLsR1i9kJ5BRvNyzdx/E2vorIsukuDrbo8e3iZ11JMgCOVrmC8Eq9YkHBqgwX4UnrPumjFyvGMZ2Q==
-  dependencies:
-    "@sentry/types" "5.7.1"
-    tslib "^1.9.3"
-
 "@sindresorhus/is@^0.7.0":
   version "0.7.0"
   resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd"
@@ -1952,13 +1878,6 @@ adjust-sourcemap-loader@2.0.0:
     object-path "0.11.4"
     regex-parser "2.2.10"
 
-agent-base@^4.3.0:
-  version "4.3.0"
-  resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
-  integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==
-  dependencies:
-    es6-promisify "^5.0.0"
-
 agentkeepalive@3.4.1:
   version "3.4.1"
   resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.4.1.tgz#aa95aebc3a749bca5ed53e3880a09f5235b48f0c"
@@ -3211,11 +3130,6 @@ convert-source-map@^0.3.3:
   resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-0.3.5.tgz#f1d802950af7dd2631a1febe0596550c86ab3190"
   integrity sha1-8dgClQr33SYxof6+BZZVDIarMZA=
 
-cookie@^0.3.1:
-  version "0.3.1"
-  resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
-  integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=
-
 copy-concurrently@^1.0.0:
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0"
@@ -4108,18 +4022,11 @@ es6-iterator@2.0.3, es6-iterator@~2.0.3:
     es5-ext "^0.10.35"
     es6-symbol "^3.1.1"
 
-es6-promise@^4.0.3, es6-promise@^4.1.0:
+es6-promise@^4.1.0:
   version "4.2.8"
   resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
   integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
 
-es6-promisify@^5.0.0:
-  version "5.0.0"
-  resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
-  integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=
-  dependencies:
-    es6-promise "^4.0.3"
-
 es6-symbol@^3.1.1, es6-symbol@~3.1.3:
   version "3.1.3"
   resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18"
@@ -5223,14 +5130,6 @@ https-browserify@^1.0.0:
   resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
   integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
 
-https-proxy-agent@^3.0.0:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz#b8c286433e87602311b01c8ea34413d856a4af81"
-  integrity sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg==
-  dependencies:
-    agent-base "^4.3.0"
-    debug "^3.1.0"
-
 human-signals@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
@@ -6150,11 +6049,6 @@ lru-cache@^4.0.1:
     pseudomap "^1.0.2"
     yallist "^2.1.2"
 
-lru_map@^0.3.3:
-  version "0.3.3"
-  resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd"
-  integrity sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=
-
 magic-string@^0.25.1:
   version "0.25.7"
   resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
@@ -9697,7 +9591,7 @@ ts-pnp@^1.1.6:
   resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92"
   integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==
 
-tslib@^1.10.0, tslib@^1.9.0, tslib@^1.9.3:
+tslib@^1.10.0, tslib@^1.9.0:
   version "1.13.0"
   resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043"
   integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==
diff --git a/src/core/queryCache.js b/src/core/queryCache.js
index 5b59c38c8..546ecd3c4 100644
--- a/src/core/queryCache.js
+++ b/src/core/queryCache.js
@@ -17,7 +17,22 @@ export function makeQueryCache({ frozen = false, defaultConfig } = {}) {
   const globalListeners = []
 
   const configRef = defaultConfig
-    ? { current: { ...defaultConfigRef.current, ...defaultConfig } }
+    ? {
+        current: {
+          shared: {
+            ...defaultConfigRef.current.shared,
+            ...defaultConfig.shared,
+          },
+          queries: {
+            ...defaultConfigRef.current.queries,
+            ...defaultConfig.queries,
+          },
+          mutations: {
+            ...defaultConfigRef.current.mutations,
+            ...defaultConfig.mutations,
+          },
+        },
+      }
     : defaultConfigRef
 
   const queryCache = {


Test patch:
diff --git a/src/core/tests/queryCache.test.js b/src/core/tests/queryCache.test.js
index cc5bdff95..35cd00f34 100644
--- a/src/core/tests/queryCache.test.js
+++ b/src/core/tests/queryCache.test.js
@@ -1,5 +1,6 @@
 import { sleep } from './utils'
 import { queryCache, queryCaches } from '../'
+import { makeQueryCache } from '../queryCache'
 
 describe('queryCache', () => {
   afterEach(() => {
@@ -184,7 +185,10 @@ describe('queryCache', () => {
   test('query interval is cleared when unsubscribed to a refetchInterval query', async () => {
     const queryKey = 'key'
     const fetchData = () => Promise.resolve('data')
-    await queryCache.prefetchQuery(queryKey, fetchData, { cacheTime: 0, refetchInterval: 1 })
+    await queryCache.prefetchQuery(queryKey, fetchData, {
+      cacheTime: 0,
+      refetchInterval: 1,
+    })
     const query = queryCache.getQuery(queryKey)
     const instance = query.subscribe()
     instance.updateConfig(query.config)
@@ -224,4 +228,15 @@ describe('queryCache', () => {
     expect(newQuery.state.markedForGarbageCollection).toBe(false)
     expect(newQuery.state.data).toBe('data')
   })
+
+  test('makeQueryCache merges defaultConfig so providing a queryFn does not overwrite the default queryKeySerializerFn', async () => {
+    const queryFn = () => 'data'
+    const queryCache = makeQueryCache({
+      defaultConfig: { queries: { queryFn } },
+    })
+
+    expect(() => queryCache.buildQuery('test')).not.toThrow(
+      'config.queryKeySerializerFn is not a function'
+    )
+  })
 })