reactjs - What might cause the same exact code to behave differently in a published npm package vs yarn link?
问题描述
A colleague and I maintain some internal libraries at my work. It's fairly standard TypeScript React UI component stuff. A lot (but not all) of our components use the Material UI library under the hood, with some style changes and additional props to meet our needs.
Earlier this week, a product manager messaged us and said, "hey, whenever I open a menu, the page scrolls up to the top." So we did a little investigation and found that removing a forwarded ref from the Material-UI Popper
component fixed it locally, when using yarn link to use our library code in a local instance of the same front-end application.
Success, you might think, right? We were able to reproduce the problem on our local, then we were able to make the problem go away on our local. One would assume that would mean that we were ready to publish a patch.
Except that publishing a patch didn't fix it.
We've somehow ended up in a situation where the same exact code behaves as expected when run locally via yarn link, but does not behave as expected when run either locally or in a hosted environment from a published npm package.
My question to you is: Have you ever had a problem like this? Did you ever figure out what caused it? I'm racking my brain to try to figure out what could be the difference. It's the same exact code, it's just running from a local build artifact in one case (where it works as expected), from an installed node_modules package in the other (where it does not work as expected).
for reference, here's a slightly modified version of the source code for the component in question:
import ClickAwayListener from '@material-ui/core/ClickAwayListener'
import Grow from '@material-ui/core/Grow'
import MuiMenuList from '@material-ui/core/MenuList'
import Paper from '@material-ui/core/Paper'
import Popper from '@material-ui/core/Popper'
import React from 'react'
import FocusLock from 'react-focus-lock'
import withTheme from '../hoc/withTheme'
import {MenuProps} from './Menu.model'
import style from './Menu.style'
export const Menu = withTheme(
React.forwardRef((props: MenuProps, ref: React.Ref<HTMLDivElement>) => {
const menuRef = React.useRef<HTMLDivElement>(null)
const {
children,
classes,
id,
menuButton,
open = false,
placement,
requestToggle,
testID,
transformOrigin,
} = props
const handleClose = (event: any) => {
if (menuRef.current && menuRef.current.contains(event.target)) {
return
}
requestToggle()
}
const tabEvent = (event: any) => {
const key = event.keyCode ? event.keyCode : event.which
if (key === 9 || key === 27) {
requestToggle()
}
}
return (
<div className={classes?.container} ref={ref}>
<div
ref={menuRef}
aria-owns={open ? id : undefined}
aria-haspopup='true'
onClick={requestToggle}
role='button'
>
{menuButton}
</div>
<Popper
open={open}
anchorEl={menuRef.current}
transition
className={classes?.popperRoot}
role='menu'
disablePortal
placement={placement}
>
{({TransitionProps, placement: p}) => {
const transformOriginStyle = (() => {
if (transformOrigin) {
return `${transformOrigin.horizontal} ${transformOrigin.vertical}`
}
if (p === 'bottom') {
return 'center top'
}
return 'center bottom'
})()
return (
<Grow
{...TransitionProps}
style={{
transformOrigin: transformOriginStyle,
}}
>
<Paper
className={classes?.paperRoot}
id={id}
data-testid={testID}
>
<FocusLock>
<ClickAwayListener onClickAway={handleClose}>
<MuiMenuList onKeyDown={tabEvent}>{children}</MuiMenuList>
</ClickAwayListener>
</FocusLock>
</Paper>
</Grow>
)
}}
</Popper>
</div>
)
}),
style,
)
Menu.displayName = 'Menu'
Menu.defaultProps = {
requestToggle: () => undefined,
} as Partial<MenuProps>
export default Menu
Using dev tools to manually toggle the open
prop that's passed through to the internal use of Popper
causes the scroll to top bug I'm experiencing to happen when I use the published version of the package, but not when using a yarn linked version.
解决方案
推荐阅读
- excel - 宏更改时重新计算数据验证
- c# - 在文本框中隐藏密码,除了最后一个字母
- jquery - 将项目移到开头
- javascript - JS Puppeteer 等待页面加载完成
- mongodb - 使用 Map/Reduce 合并 MongoDB 中 2 个集合之间的公共字段?
- ruby-on-rails - 渲染嵌套的 ERB 模板
- java - 如何检查列表中的列表是否不为空?
- ruby-on-rails - 在 Rails 将 4.2.9 更新到 4.2.10 后 Teaspoon 严重失败
- python-3.x - Python - Pandas:买卖订单分为多行,我想将其合并回 1 行。所以 1 个订单 = 1 行
- typescript - 如何为 Map 对象编写 TypeScript `get` 函数?