我对React还是很陌生,并且正在研究无限滚动组件。多个组件将使用无限滚动并且需要一起同步(即,滚动一个元素以编程方式也滚动其他组件)。
因此,我创建了ScrollProvider
来维护组件之间的滚动状态(即使它们已重新渲染),而较低级别的钩子useScrollSync.
useScrollState返回一个ref和一个handleScroll回调,它们可以修改状态在滚动提供程序中。一切正常。但是,我单独想测量组件的大小。 React团队提供的示例显示了一个回调,因为可以肯定的是,一旦安装了组件,该回调将被执行,并且该元素不会为null。问题在于div已经具有useScrollSync挂钩的引用。
核心问题
如果除了在其上使用滚动同步外,还想测量div,该如何为它分配一个回调ref和其他ref?假设一个元素只能有一个div,这周围是否有一种模式?
一些(简体)代码:
ScrollProvider
const ScrollContext = React.createCreateContext();
const ScrollProvider = ({initialScrollTop, initialScrollLeft}) => {
const controlledElements = useRef(new Map());
const scrollPositions = useRef({
scrollTop: initialScrollTop,
scrollLeft: initialScrollLeft,
controllingElementKey: null
});
const register = (key, controlledElementRef) => {
controlledElements.current.set(key, controlledElementRef);
}
const handleScrollHOF = (key) => {
return () => {
scrollPositions.controllingElementKey = key;
//some scrolling logic
}
}
return {register, scrollPositions, handleScrollHOF};
}
useScrollSync
const useScrollSync = () => {
const scrollContext = useContext(ScrollContext);
const elementRef = useRef(null);
const keyRef = useRef({key: Symbol()}); // this probably could also be useState
useEffect(() => {
scrollContext.register(keyRef, elementRef);
}, []);
return {ref: elementRef, handleScroll: handleScrollHOF(keyRef.current)};
}
SomeComponent(第1轮)
const SomeComponent = () => {
// this would be within the provider tree
const {ref, handleScroll} = useScrollSync();
return (
<div onScroll={handleScroll} ref={ref}>some stuff</div>
)
}
现在的挑战是添加一个测量钩子...
useMeasurements
const useMeasurements = () => {
// something like this, per the React team's Hooks FAQ
const [measurements, setMeasurements] = useState(null);
const measurementRef = useCallback((element) => {
if(element !== null) {
setMeasurements(element.getBoundingClientRect());
}
});
return {measurementRef, measurements};
}
为了将此添加到SomeComponent ... SomeComponent(第2轮)
const SomeComponent = () => {
// this would be within the provider tree
const {ref, handleScroll} = useScrollSync();
const {measurementRef, measurements} = useMeasurements();
// I cannot assign measurementRef to this same div,
// and changing useMeasurements to just measure an injected ref winds up
// with that ref being null and it never being recalculated
return (
<div onScroll={handleScroll} ref={ref}>some stuff</div>
)
}
我在这里碰壁,或者我只是太累了。关于如何超越这个范围有什么想法吗?
答案 0 :(得分:0)
我看到的主要问题是您没有在useMeasurement中引用可行的ref。另外,在创建DOM之前,useCallback作为呈现的一部分同步执行。您需要在另一个useEffect挂钩中引用您的元素。