Merge pull request #14497 from strapi/fix/relations/infinite-scroll-in-input

This commit is contained in:
Josh 2022-10-03 09:22:35 +01:00 committed by GitHub
commit b93f4cb7b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -68,6 +68,10 @@ const RelationInput = ({
const outerListRef = useRef(); const outerListRef = useRef();
const [overflow, setOverflow] = useState(''); const [overflow, setOverflow] = useState('');
const {
data: { pages },
} = searchResults;
const relations = useMemo(() => paginatedRelations.data.pages.flat(), [paginatedRelations]); const relations = useMemo(() => paginatedRelations.data.pages.flat(), [paginatedRelations]);
const totalNumberOfRelations = relations.length ?? 0; const totalNumberOfRelations = relations.length ?? 0;
@ -86,12 +90,12 @@ const RelationInput = ({
const options = useMemo( const options = useMemo(
() => () =>
searchResults.data.pages.flat().map((result) => ({ pages.flat().map((result) => ({
...result, ...result,
value: result.id, value: result.id,
label: result.mainField, label: result.mainField,
})), })),
[searchResults] [pages]
); );
useEffect(() => { useEffect(() => {
@ -135,24 +139,37 @@ const RelationInput = ({
const [isMenuOpen, setIsMenuOpen] = useState(false); const [isMenuOpen, setIsMenuOpen] = useState(false);
const timeoutRef = useRef(); const timeoutRef = useRef();
const previousOptions = useRef([]);
useEffect(() => { useEffect(() => {
setIsMenuOpen((isCurrentlyOpened) => { /**
/** * We only really want this effect to fire once when the options
* If we're currently open and the options changed * change from an empty array to an array with values.
* we want to close and open to ensure the menu's * Otherwise, it'll fire when the infinite scrolling happens causing
* position is correctly calculated * the menu to jump to the top all the time when loading more.
*/ */
if (isCurrentlyOpened) { if (options.length > 0 && previousOptions.current.length === 0) {
timeoutRef.current = setTimeout(() => { setIsMenuOpen((isCurrentlyOpened) => {
setIsMenuOpen(true); /**
}, 10); * If we're currently open and the options changed
* we want to close and open to ensure the menu's
* position is correctly calculated
*/
if (isCurrentlyOpened) {
timeoutRef.current = setTimeout(() => {
setIsMenuOpen(true);
}, 10);
return false;
}
return false; return false;
} });
}
return false; return () => {
}); previousOptions.current = options || [];
};
}, [options]); }, [options]);
useEffect(() => { useEffect(() => {