fix(ui): uses query provider as single source of truth for where builder (#11476)

The "where" builder maintains its own duplicative state for conditions.
This is problematic when an outside force needs to control the
conditions in some way, but the "where" builder will not receive those
updates.

While it is a requirement of the "where" builder to transform the
"where" query into "and" / "or" format for rendering, it does so in a
way that causes it to become out of sync with the query provider. This
is because we first initialize state from context, then for every change
to conditions, report those updates to contexts—but not the other way
around.

To fix this, we need to completely remove state from the "where" builder
and solely rely on the query context as a single source of truth. This
will allow it to receive automatic updates from query provider without
needing to sync both local state and context simultaneously. Now, we
only ever need to send updates to the query provider and let the
top-down rendering cycle propagate those changes everywhere.
This commit is contained in:
Jacob Fletcher
2025-03-01 16:20:00 -05:00
committed by GitHub
parent dda17f0c32
commit 927078c4db
2 changed files with 6 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
'use client' 'use client'
import type { Operator, Where } from 'payload' import type { Operator } from 'payload'
import { getTranslation } from '@payloadcms/translations' import { getTranslation } from '@payloadcms/translations'
import React, { useMemo } from 'react' import React, { useMemo } from 'react'
@@ -32,7 +32,7 @@ export const WhereBuilder: React.FC<WhereBuilderProps> = (props) => {
const { handleWhereChange, query } = useListQuery() const { handleWhereChange, query } = useListQuery()
const [conditions, setConditions] = React.useState<Where[]>(() => { const conditions = useMemo(() => {
const whereFromSearch = query.where const whereFromSearch = query.where
if (whereFromSearch) { if (whereFromSearch) {
@@ -51,7 +51,7 @@ export const WhereBuilder: React.FC<WhereBuilderProps> = (props) => {
} }
return [] return []
}) }, [query.where])
const addCondition: AddCondition = React.useCallback( const addCondition: AddCondition = React.useCallback(
async ({ andIndex, field, orIndex, relation }) => { async ({ andIndex, field, orIndex, relation }) => {
@@ -77,8 +77,7 @@ export const WhereBuilder: React.FC<WhereBuilderProps> = (props) => {
}) })
} }
setConditions(newConditions) await handleWhereChange({ or: newConditions })
await handleWhereChange({ or: conditions })
}, },
[conditions, handleWhereChange], [conditions, handleWhereChange],
) )
@@ -100,8 +99,7 @@ export const WhereBuilder: React.FC<WhereBuilderProps> = (props) => {
const newConditions = [...conditions] const newConditions = [...conditions]
newConditions[orIndex].and[andIndex] = newRowCondition newConditions[orIndex].and[andIndex] = newRowCondition
setConditions(newConditions) await handleWhereChange({ or: newConditions })
await handleWhereChange({ or: conditions })
} }
}, },
[conditions, handleWhereChange], [conditions, handleWhereChange],
@@ -116,8 +114,7 @@ export const WhereBuilder: React.FC<WhereBuilderProps> = (props) => {
newConditions.splice(orIndex, 1) newConditions.splice(orIndex, 1)
} }
setConditions(newConditions) await handleWhereChange({ or: newConditions })
await handleWhereChange({ or: conditions })
}, },
[conditions, handleWhereChange], [conditions, handleWhereChange],
) )

View File

@@ -45,13 +45,6 @@ export const ListQueryProvider: React.FC<ListQueryProps> = ({
} }
}) })
// If the search params change externally, update the current query
useEffect(() => {
if (modifySearchParams) {
setCurrentQuery(searchParams)
}
}, [searchParams, modifySearchParams])
const refineListData = useCallback( const refineListData = useCallback(
// eslint-disable-next-line @typescript-eslint/require-await // eslint-disable-next-line @typescript-eslint/require-await
async (query: ListQuery) => { async (query: ListQuery) => {