我有一个有趣的错误,我似乎无法解决,希望我的React知识比我更好的人可以帮助我解决。
基本上,我有一个组件(滑块轮播,如Netflix队列),它试图设置两个元素(左右导航的导航滑块按钮)的可见性,如果底层开发人员溢出和/或基础div位于某个位置。当onComponentDidMount,基础div的位置发生更改并带有窗口调整大小事件侦听器时,将调用我的可见性设置器方法。
大多数情况下,它的工作情况与预期的一样,但是,我有一个边缘情况,即使转到新路线后,我也可以调整窗口的大小,并且可以按预期工作...但是,如果我走了一条新路线再次调整窗口大小时出现错误。
似乎第二次切换路由后未设置参考,因为它们返回null。
我尝试检测ref是否为null,但无法正常工作。
setCaretVis() {
const el = this.tray.current;
console.log(el);
const parent = this.wrapper.current;
console.log(parent);
const posRight = this.offsetRight();
const posLeft = el.scrollLeft;
const left = this.caretLeft.current;
const right = this.caretRight.current;
const parWidth = el.parentElement.offsetWidth;
const width = el.scrollWidth;
if (parWidth >= width) {
if (!left.classList.contains("invis")) {
left.classList.add("invis");
} else if (left.classList.contains("invis")) {
}
if (!right.classList.contains("invis")) {
right.classList.add("invis");
}
} else if (parWidth < width) {
if (left.classList.contains("invis") && posLeft != 0) {
left.classList.remove("invis");
} else if (!left.classList.contains("invis") && posLeft === 0) {
left.classList.add("invis");
}
if (right.classList.contains("invis") && posRight != 0) {
right.classList.remove("invis");
} else if (!right.classList.contains("invis") && posRight === 0) {
right.classList.add("invis");
}
}
if (posLeft > 0) {
left.classList.remove("invis");
} else {
left.classList.add("invis");
}
if (posRight === 0) {
console.log("true");
right.classList.add("invis");
} else {
right.classList.remove("invis");
}
}
offsetRight() {
const el = this.tray.current;
//const element = this.refs.tray;
const parent = this.wrapper.current;
const parWidth = parent.offsetWidth;
const width = el.scrollWidth;
const left = el.scrollLeft;
let sub = width - parWidth;
let calc = Math.abs(left - sub);
return calc;
};
// The componentDidMount method
componentDidMount() {
this.setCaretVis();
window.addEventListener("resize", this.setCaretVis);
this.setCaretVis();
}
我想在更改路线后设置大小调整的可见性(添加/删除css类),而不会出现错误。
当前错误读取:未捕获的TypeError:无法读取null的属性'offsetWidth'
答案 0 :(得分:1)
我怀疑再次进入新路线时会重新创建您的组件,但是resize
处理程序仍会调用旧的侦听器。尝试删除componentWillUnmount
中的事件监听器:
componentDidMount() {
this.setCaretVis();
window.addEventListener("resize", this.setCaretVis);
this.setCaretVis();
}
componentWillUnmount() {
window.removeEventListener("resize", this.setCaretVis);
}
路由器重新创建组件时,它将再次订阅resize
事件。
从文档中
componentWillUnmount()在卸载和销毁组件之前立即被调用。使用此方法执行任何必要的清除,例如使计时器无效,取消网络请求或清除在componentDidMount中创建的所有DOM元素