如何将 onScroll 处理程序添加到 react-select 组件的 menuList?
How do I add an onScroll handler to the menuList of a react-select component?
我想将 onScroll 处理程序添加到 react-select 组件的 menuList,但以下内容不起作用。我怀疑我需要为其中一个子项设置 onScroll
而不是包含子项的元素,但我不知道该怎么做。
import React from 'react';
import Select, { components, MenuListProps } from 'react-select';
import {
ColourOption,
colourOptions,
FlavourOption,
GroupedOption,
groupedOptions,
} from './docs/data';
const handleScroll = () =>{
console.log('scrolling')
}
const MenuList = (
props: MenuListProps<ColourOption | FlavourOption, false, GroupedOption>
) => {
return (
<components.MenuList {...props}>
<div onScroll={handleScroll}>
{props.children}
</div>
</components.MenuList>
);
};
export default () => (
<Select<ColourOption | FlavourOption, false, GroupedOption>
defaultValue={colourOptions[1]}
menuIsOpen={true}
options={groupedOptions}
components={{ MenuList }}
/>
);
https://codesandbox.io/s/codesandboxer-example-forked-jr74k?file=/example.tsx:0-721
我也试过用这样的东西
mySelectRef.current.menuListRef.addEventListener("scroll", handleScroll)
但 .current
或 .current.menuListRef
在执行命令时始终未定义或为空。我尝试使用 React.useEffect 和 setTimeout,但效果不佳。我希望我可以通过设置右内部 div.
的 onScroll
来完成此操作
理由
理想情况下,您不会从头开始实现自定义处理程序,而是重用或从已经存在并由开源社区维护的挂钩开始。
当你自己实现它时,有一些注意事项,比如事件监听器必须是被动的,你必须使用 React 的 useEffect
钩子注册和注销监听器。
例子
有很多这样的例子。一个可能是 implementation from react-use.
实施
您的组件可能如下所示:
const Component = () => {
const ref = useRef();
const { x, y } = useScroll(ref);
return <MyComponent ref={ref} />
}
您需要用 div
包装您的 MenuList
组件并向此组件提供 ref
,然后访问此 HTML 的直接 div 子级零件。然后你可以为这个元素定义onscroll
函数。
const MenuList = (
props: MenuListProps<ColourOption | FlavourOption, false, GroupedOption>
) => {
const menuListRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (menuListRef.current) {
menuListRef.current.querySelector("div").onscroll = () => {
console.log("scrolling");
};
}
}, [menuListRef]);
return (
<div ref={menuListRef}>
<components.MenuList {...props}>
<div>{props.children}</div>
</components.MenuList>
</div>
);
};
方法
我试图找出是否可以访问已经支持 onScroll
属性 的本机包装器元素。如果深入研究 components documentation,您会发现 Menu
组件接受 innerProps
,这是每个 HTML 元素接受的常规 HTMLAttributes
。所以我所做的是提供一个 onScroll
属性 到 innerProps
.
代码
const Menu = (
props: MenuProps<ColourOption | FlavourOption, false, GroupedOption>
) => {
const handleScroll = () => {
console.log("scrolling");
};
return (
<components.Menu
{...props}
innerProps={{ ...props.innerProps, onScroll: handleScroll }}
>
{props.children}
</components.Menu>
);
};
export default () => (
<Select<ColourOption | FlavourOption, false, GroupedOption>
defaultValue={colourOptions[1]}
menuIsOpen={true}
options={groupedOptions}
components={{ Menu }}
/>
);
工作示例
我想将 onScroll 处理程序添加到 react-select 组件的 menuList,但以下内容不起作用。我怀疑我需要为其中一个子项设置 onScroll
而不是包含子项的元素,但我不知道该怎么做。
import React from 'react';
import Select, { components, MenuListProps } from 'react-select';
import {
ColourOption,
colourOptions,
FlavourOption,
GroupedOption,
groupedOptions,
} from './docs/data';
const handleScroll = () =>{
console.log('scrolling')
}
const MenuList = (
props: MenuListProps<ColourOption | FlavourOption, false, GroupedOption>
) => {
return (
<components.MenuList {...props}>
<div onScroll={handleScroll}>
{props.children}
</div>
</components.MenuList>
);
};
export default () => (
<Select<ColourOption | FlavourOption, false, GroupedOption>
defaultValue={colourOptions[1]}
menuIsOpen={true}
options={groupedOptions}
components={{ MenuList }}
/>
);
https://codesandbox.io/s/codesandboxer-example-forked-jr74k?file=/example.tsx:0-721
我也试过用这样的东西
mySelectRef.current.menuListRef.addEventListener("scroll", handleScroll)
但 .current
或 .current.menuListRef
在执行命令时始终未定义或为空。我尝试使用 React.useEffect 和 setTimeout,但效果不佳。我希望我可以通过设置右内部 div.
onScroll
来完成此操作
理由
理想情况下,您不会从头开始实现自定义处理程序,而是重用或从已经存在并由开源社区维护的挂钩开始。
当你自己实现它时,有一些注意事项,比如事件监听器必须是被动的,你必须使用 React 的 useEffect
钩子注册和注销监听器。
例子
有很多这样的例子。一个可能是 implementation from react-use.
实施
您的组件可能如下所示:
const Component = () => {
const ref = useRef();
const { x, y } = useScroll(ref);
return <MyComponent ref={ref} />
}
您需要用 div
包装您的 MenuList
组件并向此组件提供 ref
,然后访问此 HTML 的直接 div 子级零件。然后你可以为这个元素定义onscroll
函数。
const MenuList = (
props: MenuListProps<ColourOption | FlavourOption, false, GroupedOption>
) => {
const menuListRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (menuListRef.current) {
menuListRef.current.querySelector("div").onscroll = () => {
console.log("scrolling");
};
}
}, [menuListRef]);
return (
<div ref={menuListRef}>
<components.MenuList {...props}>
<div>{props.children}</div>
</components.MenuList>
</div>
);
};
方法
我试图找出是否可以访问已经支持 onScroll
属性 的本机包装器元素。如果深入研究 components documentation,您会发现 Menu
组件接受 innerProps
,这是每个 HTML 元素接受的常规 HTMLAttributes
。所以我所做的是提供一个 onScroll
属性 到 innerProps
.
代码
const Menu = (
props: MenuProps<ColourOption | FlavourOption, false, GroupedOption>
) => {
const handleScroll = () => {
console.log("scrolling");
};
return (
<components.Menu
{...props}
innerProps={{ ...props.innerProps, onScroll: handleScroll }}
>
{props.children}
</components.Menu>
);
};
export default () => (
<Select<ColourOption | FlavourOption, false, GroupedOption>
defaultValue={colourOptions[1]}
menuIsOpen={true}
options={groupedOptions}
components={{ Menu }}
/>
);