I want to re-render documentList
based on selectedId
.
Normally i would just react useState
or vue’s ref
for the selectedId
and then rerender the UI with useEffect
or computed()
if the value changes.
But here in sanity structure builder API, it’s not allowed to use hooks.
Note: the filter works on load, selectedId
changes correctly onChange, the only issue is that the UI is not being rerendered when the selectedId
changes.
import type { StructureResolver } from 'sanity/structure';
import { createElement } from 'react';
import { EventFilterDropdown } from '../components/event-filter-dropdown';
export const FilterStructure: StructureResolver = (S) => {
let selectedId;
return S.list()
.title('Content')
.items([
S.listItem()
.title('Attendees by Event')
.child(
S.component()
.title('Event Filter')
.component(() =>
createElement(EventFilterDropdown, {
onChange: (id: string) => {
selectedId = id;
console.log(selectedId);
return selectedId;
},
}),
).child(
selectedId
? S.documentList()
.title('Attendees')
.filter('_type == "attendee" && event._ref == $eventId')
.params({ eventId: x })
: S.documentList()
.title('Attendees')
.filter('_type == "attendee"'),
),
),
...S.documentTypeListItems().filter(
(listItem) => listItem.getId() as string,
),
]);
};
the event component itself is a simple option select component that returns the id
of an event that the user is selecting.
import { Select, Stack } from '@sanity/ui';
import React, { useEffect, useRef, useState } from 'react';
import { useClient } from 'sanity';
export function EventFilterDropdown({ onChange }) {
const ref = useRef('ref');
const [events, setEvents] = useState([]);
const client = useClient({ apiVersion: '2024-06-01' });
useEffect(() => {
client.fetch('*[_type == "event" && count(*[_type == "attendee" && references(^._id)]) > 0]')
.then(setEvents);
}, [client]);
const handleChange = (event) => {
const eventId = event.currentTarget.value;
onChange(eventId);
};
return (
<Stack space={ 2 }>
<Select onChange={ handleChange }>
<option value="">All Events</option>
{ events.map((event) => (
<option key={ event._id } ref={ ref } value={ event._id }>
{ event.name }
</option>
)) }
</Select>
</Stack>
);
}
I tried accessing react hooks here but it is not allowed, i tried several plugins but still doesnt work.
Dhia Rizqullah is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.