如何在多个组件之间共享单个MUI useScrollTrigger返回值



我目前正在使用MUI的useScrollTrigger挂钩来确定三个组件的外观-NavBar、后FAB和返回顶部按钮,例如:

export default function NavBar() {
const isScrolledDown = useScrollTrigger({ target: window, threshold: 100 });
return (
<>
<Slide in={!isScrolledDown} >
<AppBar>
<Toolbar>
</Toolbar>
</AppBar>
</Slide>
<Toolbar />
<BackToTopFAB isScrolledDown={isScrolledDown} />
<PostCreateFAB isScrolledDown={isScrolledDown} />
</>
);
}

由于我不想让浏览器监听三个单独的";滚动";事件,我当前正在将钩子的返回值从NavBar钻取到这两个按钮中。

然而,结果是,我无法将这两个按钮与NavBar解耦。

有人对如何实现这一点有任何建议吗?这样所有三个组件都共享相同的挂钩返回值?如果具有多个";滚动";听众不是DOM密集型的,我也愿意考虑

React钩子被设计为可重复使用,您可能希望将useScrollTrigger钩子移动到需要它的组件,如下所示:

const useCustomScrollTrigger = () => useScrollTrigger({ target: window, threshold: 100 });
const BackToTopFAB = () => {
const isScrolledDown = useCustomScrollTrigger();
return (...)
}
const PostCreateFAB = () => {
const isScrolledDown = useCustomScrollTrigger();
return (...)
}
const MyAppBar = () => {
const isScrolledDown = useCustomScrollTrigger();
return (
<Slide in={!isScrolledDown} >
<AppBar />
</Slide>
)
}
export default function NavBar() {
return (
<>
<MyAppBar />
<OtherContent />
<BackToTopFAB />
<PostCreateFAB />
</>
);
}

这样做有几个优点:

  • 您的代码更容易阅读,因为逻辑隐藏在每个特定组件中。在权衡IMO时,代码可读性是最重要的因素之一。几个额外的事件侦听器永远不会以任何方式影响应用程序的性能。

  • 提高父组件的性能,因为顶级组件中没有道具,如果isScrolledDown状态发生更改,则只会重新渲染3个孤立的组件。否则,页面中的其他组件(如OtherContent(也需要渲染,因为父组件中的状态发生了变化。

如果你想将状态存储在一个地方,并在组件中的任何地方访问它,无论它在层次结构中的位置如何,你也可以查看一些反应状态管理库,如redux toolkit:

import { createSlice } from '@reduxjs/toolkit'
const { actions } = createSlice({
name: 'globalState',
initialState: { isScrolledDown: false },
reducers: {
setIsScrolledDown: (state, action) => {
state.isScrolledDown = action.payload
},
},
})
const ScrollLisenter = () => {
const isScrolledDown = useScrollTrigger({ /* ... */ });
const dispatch = useDispatch()
useEffect(() => {
dispatch(actions.setIsScrolledDown(isScrolledDown));
}, [isScrolledDown]);
return null
}
const BackToTopFAB = () => {
const isScrolledDown = useSelector(state => state.globalState.isScrolledDown);
return (...)
}
const PostCreateFAB = () => {
const isScrolledDown = useSelector(state => state.globalState.isScrolledDown);
return (...)
}
<App>
<ScrollLisenter />
<NavBar />
</App>

相关问题

  • 添加过多的事件侦听器会影响性能吗

最新更新