feat: keepPreviousResult
This commit is contained in:
@@ -42,6 +42,8 @@
|
||||
|
||||
- `throttle`: Throttle interval in ms.
|
||||
|
||||
- `keepPreviousResult`: (default: `false`) Whether or not to keep previous result when the query is fetch again (for example when a variable changes). This can be useful to prevent a flash of empty content.
|
||||
|
||||
## Return
|
||||
|
||||
- `result`: result data object.
|
||||
|
||||
@@ -34,7 +34,6 @@ export default defineComponent({
|
||||
id: props.id,
|
||||
}), {
|
||||
notifyOnNetworkStatusChange: true,
|
||||
keepPreviousResult: true,
|
||||
})
|
||||
const channel = computed(() => result.value?.channel)
|
||||
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
<script lang="ts" setup>
|
||||
import { useApolloClient, useQuery } from '@vue/apollo-composable'
|
||||
import gql from 'graphql-tag'
|
||||
import { computed, ref } from 'vue'
|
||||
import MessageItem from './MessageItem.vue'
|
||||
|
||||
interface Channel {
|
||||
id: string
|
||||
label: string
|
||||
}
|
||||
|
||||
const keepPreviousResult = ref(false)
|
||||
|
||||
const channelsQuery = useQuery<{ channels: Channel[] }>(gql`
|
||||
query channels {
|
||||
channels {
|
||||
id
|
||||
label
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
const channels = computed(() => channelsQuery.result.value?.channels ?? [])
|
||||
|
||||
const selectedChannelId = ref<string | null>(null)
|
||||
|
||||
const selectedChannelQuery = useQuery(gql`
|
||||
query channel ($id: ID!) {
|
||||
channel (id: $id) {
|
||||
id
|
||||
label
|
||||
messages {
|
||||
id
|
||||
text
|
||||
}
|
||||
}
|
||||
}
|
||||
`, () => ({
|
||||
id: selectedChannelId.value,
|
||||
}), () => ({
|
||||
enabled: !!selectedChannelId.value,
|
||||
fetchPolicy: 'cache-and-network',
|
||||
keepPreviousResult: keepPreviousResult.value,
|
||||
}))
|
||||
|
||||
const selectedChannel = computed(() => selectedChannelQuery.result.value?.channel)
|
||||
|
||||
const { client: apolloClient } = useApolloClient()
|
||||
|
||||
function clearCache () {
|
||||
apolloClient.clearStore()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-full flex flex-col">
|
||||
<div class="p-4">
|
||||
<label>
|
||||
<input
|
||||
v-model="keepPreviousResult"
|
||||
type="checkbox"
|
||||
>
|
||||
keepPreviousResult
|
||||
</label>
|
||||
|
||||
<button
|
||||
class="ml-4 underline"
|
||||
@click="clearCache"
|
||||
>
|
||||
Clear cache
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="flex h-full">
|
||||
<div class="flex flex-col">
|
||||
<button
|
||||
v-for="channel of channels"
|
||||
:key="channel.id"
|
||||
class="channel-btn p-4"
|
||||
:class="{
|
||||
'bg-green-200': selectedChannelId === channel.id,
|
||||
}"
|
||||
@click="selectedChannelId = channel.id"
|
||||
>
|
||||
{{ channel.label }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="selectedChannel"
|
||||
class="the-channel flex flex-col w-full h-full overflow-auto"
|
||||
>
|
||||
<div class="flex-none p-6 border-b border-gray-200 bg-white">
|
||||
# {{ selectedChannel.label }}
|
||||
</div>
|
||||
|
||||
<div class="flex-1 overflow-y-auto">
|
||||
<MessageItem
|
||||
v-for="message of selectedChannel.messages"
|
||||
:key="message.id"
|
||||
:message="message"
|
||||
class="m-2"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-else
|
||||
class="no-data"
|
||||
>
|
||||
No data
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -42,5 +42,9 @@ export const router = createRouter({
|
||||
path: '/on-result',
|
||||
component: () => import('./components/OnResult.vue'),
|
||||
},
|
||||
{
|
||||
path: '/keep-previous-result',
|
||||
component: () => import('./components/KeepPreviousResult.vue'),
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
describe('keepPreviousResult', () => {
|
||||
beforeEach(() => {
|
||||
cy.task('db:reset')
|
||||
cy.visit('/keep-previous-result')
|
||||
})
|
||||
|
||||
it('keepPreviousResult disabled: should clear previous data', () => {
|
||||
cy.get('.no-data').should('be.visible')
|
||||
cy.get('.channel-btn').eq(0).click()
|
||||
cy.get('.no-data').should('be.visible')
|
||||
cy.get('.the-channel').should('contain.text', '# General')
|
||||
cy.get('.no-data').should('not.exist')
|
||||
cy.get('.channel-btn').eq(1).click()
|
||||
cy.get('.no-data').should('be.visible')
|
||||
cy.get('.the-channel').should('contain.text', '# Random')
|
||||
cy.get('.no-data').should('not.exist')
|
||||
})
|
||||
|
||||
it('keepPreviousResult enabled: should display previous channel', () => {
|
||||
cy.get('label').contains('keepPreviousResult').get('input[type="checkbox"]').check()
|
||||
cy.get('.no-data').should('be.visible')
|
||||
cy.get('.channel-btn').eq(0).click()
|
||||
cy.get('.no-data').should('be.visible')
|
||||
cy.get('.the-channel').should('contain.text', '# General')
|
||||
cy.get('.no-data').should('not.exist')
|
||||
cy.get('.channel-btn').eq(1).click()
|
||||
cy.get('.no-data').should('not.exist')
|
||||
cy.get('.the-channel').should('contain.text', '# General')
|
||||
cy.get('.the-channel').should('contain.text', '# Random')
|
||||
})
|
||||
})
|
||||
@@ -44,6 +44,7 @@ export interface UseQueryOptions<
|
||||
throttle?: number
|
||||
debounce?: number
|
||||
prefetch?: boolean
|
||||
keepPreviousResult?: boolean
|
||||
}
|
||||
|
||||
interface SubscribeToMoreItem {
|
||||
@@ -256,7 +257,7 @@ export function useQueryImpl<
|
||||
|
||||
// Make the cache data available to the component immediately
|
||||
// This prevents SSR hydration mismatches
|
||||
if (!isServer && (currentOptions.value?.fetchPolicy !== 'no-cache' || currentOptions.value.notifyOnNetworkStatusChange)) {
|
||||
if (!isServer && !currentOptions.value?.keepPreviousResult && (currentOptions.value?.fetchPolicy !== 'no-cache' || currentOptions.value.notifyOnNetworkStatusChange)) {
|
||||
const currentResult = query.value.getCurrentResult(false)
|
||||
|
||||
if (!currentResult.loading || currentResult.partial || currentOptions.value?.notifyOnNetworkStatusChange) {
|
||||
|
||||
Reference in New Issue
Block a user