React TypeError:无法读取未定义的属性“getBoundingClientRect”
Posted
技术标签:
【中文标题】React TypeError:无法读取未定义的属性“getBoundingClientRect”【英文标题】:React TypeError: Cannot read property 'getBoundingClientRect' of undefined 【发布时间】:2021-04-17 02:02:42 【问题描述】:服务器:Node.js、MongoDB、Graphql前端:React --typescript、apollo-client、Graphql
我认为带来数据并渲染它是时间或顺序的问题。尽管如此,我还是找不到解决这个问题的办法。
错误
-
未捕获的类型错误:无法读取未定义的属性“getBoundingClientRect”。
未捕获(承诺中)类型错误:无法读取未定义的属性“getBoundingClientRect”。
代码
import React, MutableRefObject, useCallback, useLayoutEffect, useRef, useState from 'react';
import gql, useQuery from '@apollo/client';
import MainSlide from '../../components';
import MSlidersItf, MSlideItf from '../../types';
import * as S from './MainSliderStyle';
import GetWindowWidth from '../../api/window-width/WindowWidth';
const GET_MAINSLIDERS = gql`
query
getMainSliders
idx
title
en
ko
text
en
ko
url
src
postingDate
`;
const SlideMapForm = (item: MSlideItf, i: number, Count: number) =>
return (
<MainSlide
key=String(i + Count)
title=item.title
text=item.text
url=item.url
src=item.src
postingDate=item.postingDate
/>
);
;
export default function TestBtn()
const loading, error, data = useQuery<MSlidersItf>(GET_MAINSLIDERS);
const MSlidersLength = data && data?.getMainSliders.length;
const TotalSlideCount = MSlidersLength! + 4;
// Ref
const slidersRef = useRef() as MutableRefObject<htmlDivElement>;
// getSize
const windowWidth: number = GetWindowWidth(); // Browser window width
const [elWidth, setElWidth] = useState(0);
ERROR----------------------------------------------------------------------------------------
const getEleWidth = useCallback(() =>
if (data)
const width = slidersRef.current.children[2].getBoundingClientRect();
setElWidth(width + 16); // Add Slide Margin
, [data]);
ERROR----------------------------------------------------------------------------------------
const sliderMargin: number = (windowWidth - elWidth) / 2;
// Slide to Center
const [center, setCenter] = useState(2);
const sliderPosition: number = elWidth * center - sliderMargin; // Slide Position Inital Value
// sliderControll
const prevButton = () => setCenter(center - 1);
const nextButton = () => setCenter(center + 1);
useLayoutEffect(() =>
ERROR----------------------------------------------------------------------------------------
getEleWidth();
ERROR----------------------------------------------------------------------------------------
const resizeLitener = () =>
const timing = setTimeout(() => getEleWidth(), 150);
clearTimeout(timing);
;
window.addEventListener('resize', resizeLitener);
window.addEventListener('load', resizeLitener);
return () =>
window.removeEventListener('resize', resizeLitener);
window.removeEventListener('load', resizeLitener);
;
, [TotalSlideCount, center, data, elWidth, getEleWidth, sliderPosition]);
if (loading) return <h1>Loding...</h1>;
if (error) return console.log(`MainSliders DB Error $error`);
return (
<S.Wrap>
data && (
<S.SlidersArea ref=slidersRef position=sliderPosition>
Object.values(data.getMainSliders)
.slice(-2)
.map((item, i) => SlideMapForm(item, i, -MSlidersLength!))
Object.values(data.getMainSliders).map((item, i) => SlideMapForm(item, i, 0))
Object.values(data.getMainSliders)
.slice(-2)
.map((item, i) => SlideMapForm(item, i, MSlidersLength!))
</S.SlidersArea>
)
<S.Arrows onClick=prevButton>
<S.Prev>
<img src="/img/icon/arrow-next.svg" />
</S.Prev>
<S.Next onClick=nextButton>
<img src="/img/icon/arrow-next.svg" />
</S.Next>
</S.Arrows>
</S.Wrap>
);
【问题讨论】:
【参考方案1】:试试这个:
const getEleWidth = useCallback(() =>
if (data)
const defaultValue = width: 0 ;
const width = slidersRef.current?.children?[2]?.getBoundingClientRect?.() || defaultValue; // just check if the element you want exist
setElWidth(width + 16);
, [data, slidersRef.current]); //<=== add slidersRef to your dependencies
【讨论】:
【参考方案2】:除了检查对象是否存在(如 Taghi Khavari 提到的),您可以尝试给它一个超时,以便您可以正确渲染您的 dom 元素。 它从来都不是最好的解决方案,但它可以让你的脚本快速运行。
(打算使用Taghi的解决方案)
const defaultValue = width: 0 ;
setTimeout( () =>
const width = slidersRef.current?.children?[2]?.getBoundingClientRect?.() || defaultValue; // just check if the element you want exist
setElWidth(width + 16);, 20) // You can change the number of milliseconds depending on your rendering
【讨论】:
以上是关于React TypeError:无法读取未定义的属性“getBoundingClientRect”的主要内容,如果未能解决你的问题,请参考以下文章
React - TypeError:无法读取未定义的属性“img”
TypeError:无法读取未定义的属性“长度”(React,heroku)
未处理的拒绝(TypeError):在 React 中使用 useRef 时无法读取未定义的属性(读取“值”)
React Native - TypeError:无法读取未定义的属性“干净”