React Image Preload 和 React-Slick 的错误
Posted
技术标签:
【中文标题】React Image Preload 和 React-Slick 的错误【英文标题】:Errors with React Image Preload and React-Slick 【发布时间】:2019-09-18 00:14:42 【问题描述】:问题:
我将 react-slick 与 react-preload-image(两者的最新版本)结合使用来创建具有多个滑轨的页面。这个想法是按类别显示我的作品集,因此我使用 react-slick 列出每个类别以显示图像,并使用 react-preload-image 显示预加载图像,然后显示作品集图像。
好消息是,只要我不调整浏览器窗口的大小,它就会看起来很棒并且完全符合我的要求。坏消息是,当我缩小浏览器窗口(减小宽度)时,应用程序完全崩溃 - 空白屏幕,控制台中有很多丑陋的消息,如下所示:
Uncaught TypeError: Cannot set property 'onload' of undefined
at PreloadImage.componentWillUnmount (index.js:66)
at callComponentWillUnmountWithTimer (react-dom.development.js:19866)
at htmlUnknownElement.callCallback (react-dom.development.js:347)
at Object.invokeGuardedCallbackDev (react-dom.development.js:397)
at invokeGuardedCallback (react-dom.development.js:454)
at safelyCallComponentWillUnmount (react-dom.development.js:19873)
at commitUnmount (react-dom.development.js:20293)
at commitNestedUnmounts (react-dom.development.js:20349)
at unmountHostComponents (react-dom.development.js:20645)
问题似乎发生在 react-preload-image 上。每张图片我都会得到其中一个条目(所以 40 张图片,其中 40 条警告)。
我已经以几种不同的方式对其进行了重构以尝试解决此问题,但均无济于事。这是我的组件及其代码:
PortCatRails.js - 创建所有轨道
return (
<div>
portcats.map((cat) =>
return (
<PortfolioRail key=uuid() title=cat.name catId=cat.id />
)
)
</div>
);
PortfolioRail.js - 使用 react-slick 创建每个导轨
class PortfolioRail extends React.Component
constructor(props)
super(props)
render()
const portItems = this.props.portfolio.filter((item) =>
return (item.portcats && item.portcats.indexOf(this.props.catId+'') !== -1)
)
const settings =
dots: false,
className: "center",
centerPadding: "80px",
infinite: true,
speed: 500,
slidesToScroll: 1,
centerMode: false,
ladyLoad: true,
slidesToShow: 5,
responsive: [
breakpoint: 576,
settings:
slidesToShow: 1,
slidesToScroll: 1,
arrows: false,
swipeToSlide: true,
centerMode: true
,
breakpoint: 768,
settings:
slidesToShow: 2,
slidesToScroll: 1,
arrows: false,
swipeToSlide: true,
centerMode: true
,
breakpoint: 992,
settings:
slidesToShow: 3,
slidesToScroll: 1,
arrows: true,
centerMode: false
,
breakpoint: 1900,
settings:
slidesToShow: 4,
slidesToScroll: 1,
arrows: true,
swipeToSlide: false,
centerMode: false
]
;
return (
portItems.length > 0 &&
<div>
<h4>this.props.title</h4>
<Slider ...settings>
portItems.map((item) =>
return (
<PortRailItem data=item key=uuid() />
)
)
</Slider>
</div>
)
PortfolioRailItem.js - 轨道中每个投资组合项一个组件
const PortRailItem = (props) =>
const projectTitle, shortDesc, propcats, previewImg = props.data;
const [infoClass, setInfoClass] = useState('');
const handleMouseEnter = (e) =>
setInfoClass('railItem__info--expanded');
const handleMouseLeave = (e) =>
setInfoClass('');
return (
<div>
<div className="railItem__outer" onMouseEnter=handleMouseEnter onMouseLeave=handleMouseLeave>
<div className="railItem__inner">
<ImageWithPreloader src=previewImg className="railitem__img-preloader" />
<div className=`railItem__info $infoClass`>
<h5>projectTitle</h5>
<div className=`railItem__info--short-desc $infoClass`>
shortDesc
</div>
</div>
</div>
</div>
</div>
)
ImageWithPreloader.js - 使用预加载器显示给定图像
const ImageWithPreloader = (props) =>
const src, className = 'img-peloader', duration = '1000ms' = props;
return (
<PreloadImage
src=src
className=className
duration=duration
lazy
/>
)
最后一条线索:正如我所说,我只在缩小浏览器窗口时才会收到错误消息,而且只有在它遇到设置中的一个断点时才会出现错误,所以这不是巧合。我只是不知道在这一点上如何处理它。
如果有人见过这样的事情,我很想知道它的修复方法。这是迄今为止我唯一喜欢的图像预加载器(我已经尝试了几个)。
谢谢!
【问题讨论】:
【参考方案1】:所以我不知道这个问题是否是我的实现所独有的,但我找到了解决方法。显然 react-preload-image 中存在一些错误,但它是一个超级简单的单行修复。
在 index.js 文件的第 66 行,只需更改以下内容:
PreloadImage.prototype.componentWillUnmount = function componentWillUnmount()
if (this.observer) this.observer.disconnect();
this.preloader.onload = null;
;
到这里:
PreloadImage.prototype.componentWillUnmount = function componentWillUnmount()
if (this.observer) this.observer.disconnect();
// just add an if(this.preloader) to the next line and all is well
if(this.preloader) this.preloader.onload = null;
;
而且插件效果很好。我已经让作者知道了,希望他会在下一个版本中实现这一点。
【讨论】:
以上是关于React Image Preload 和 React-Slick 的错误的主要内容,如果未能解决你的问题,请参考以下文章
preload.ts 中的 contextBridge.exposeInMainWorld:ipcRenderer 接收到来自 main.ts 的消息但渲染器没有得到它
react-native + react-native-tab-navigator 实现 TabBar