[英]After referring to document by querySelector I get an error in my React app - everything works fine until I scroll right to the bottom
I have a React app where I put a progress bar which changes its value once the user reaches some DOM elements.我有一个 React 应用程序,我在其中放置了一个进度条,一旦用户到达一些 DOM 元素,它就会改变它的值。 To build that feature I referred to window object with its 'scroll' properties:
为了构建该功能,我参考了 window object 及其“滚动”属性:
// appointment.js
class Appointment extends React.Component {
state = {
progBarWidth: 33
}
checkCoordinates() {
const stepTwoRect = document
.querySelector('#stepTwo')
.getBoundingClientRect().top
const stepThreeRect = document
.querySelector('#stepThree')
.getBoundingClientRect().top
if (window.scrollY >= stepTwoRect && window.scrollY < stepThreeRect) {
this.setState({ progBarWidth: 66 })
}
else if (window.scrollY < stepTwoRect) {
this.setState({ progBarWidth: 33 })
}
else if (window.scrollY >= stepThreeRect) {
this.setState({ progBarWidth: 100 })
}
}
componentDidMount() {
window.addEventListener(
'scroll',
this.checkCoordinates.bind(this)
)
}
componentWillUnmount() {
window.removeEventListener(
'scroll',
this.checkCoordinates.bind(this)
)
}
render() {
return (
<React.Fragment>
<div
className="progress position-fixed"
>
<div
className="progress-bar"
style={{
width: `${this.state.progBarWidth}%`,
}}
aria-valuenow="33"
aria-valuemin="0"
aria-valuemax="100"
></div>
</div>
<h1 id="greeting"> hello ! </h1>
<h1>
Very long Lorem Ipsum to fill the page
</h1>
<h1 id="stepTwo"> Step 2 </h1>
<h1>
Again very long Lorem Ipsum
</h1>
<h1 id="stepThree"> Step 3 </h1>
<h1>
Very long Lorem Ipsum
</h1>
</div>
<div>
)
}
}
The logic is that as I said once a user reaches #stepTwo, the progress bar should be filled by 66% in contrast to initial 33%, and once the user reaches #stepThree, it should be filled by 100%.逻辑是,正如我所说,一旦用户到达#stepTwo,进度条应该被填充 66%,而最初的 33%,一旦用户到达#stepThree,它应该被填充 100%。
checkCoordinates does this function changing the state, and then that value is sent to width style property of progress bar. checkCoordinates 执行此 function 更改 state,然后将该值发送到进度条的宽度样式属性。
I also made a bind for that function when adding event listener because it killed couple of my hours.在添加事件侦听器时,我还为那个 function 做了一个绑定,因为它杀死了我几个小时。
I think the problem is either in using document so when I go to other routes the app cannot reach #stepTwo and #stepThree (which are included only in appointment.js, however React puts everything in the root in index.html in the end).我认为问题在于使用文档,所以当我 go 到其他路线时,应用程序无法到达 #stepTwo 和 #stepThree (它们仅包含在 Appointment.js 中,但是 React 将所有内容放在 index.html 的根目录中) . Or it is binding.
或者它具有约束力。
I tested in different browsers and tried to rerun the application however nothing helped me.我在不同的浏览器中进行了测试,并尝试重新运行该应用程序,但没有任何帮助。 I also get
我也得到
TypeError: Cannot read property 'getBoundingClientRect' of null
Appointment.checkCoordinates
src/Appointment/Appointment.js:36
33 | // }
34 |
35 | checkCoordinates() {
> 36 | const stepTwoRect = document
| ^ 37 | .querySelector('#stepTwo')
38 | .getBoundingClientRect().top
39 |
together with 'can't find querySelector of null'.连同“找不到 null 的 querySelector”。
Any thoughts?有什么想法吗?
PS when I just close the error by pushing X, everything works until I scroll until the very end of the page. PS当我通过按X关闭错误时,一切正常,直到我滚动到页面的最后。
PPS I noticed that when I use sass files for an individual component, styles apply to all the application components, not only the one for which it was created. PPS 我注意到,当我将 sass 文件用于单个组件时,styles 适用于所有应用程序组件,而不仅仅是为其创建的那个。 I guess probably my app seeks for #stepOne on every page scroll, and when it cannot find, it throws an error..
我想我的应用程序可能会在每个页面滚动上寻找#stepOne,当它找不到时,它会抛出一个错误..
PPPS I tried to bind the function once - just in the constructor. PPPS 我试图绑定一次 function - 只是在构造函数中。 Now I have a problem with setState
现在我遇到了 setState 的问题
So the problem was with the bind.所以问题出在绑定上。 Bind creates new function every time even though I had removeEventListener element in componentWillUnmount.
Bind 每次都会创建新的 function,即使我在 componentWillUnmount 中有 removeEventListener 元素。
Using Arrow function使用箭头 function
checkCoordinates = () => {...}
helped both to bind and to use setState.帮助绑定和使用 setState。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.