सर्वर : Node.js, MongoDB, Graphql
फ्रंट-एंड: React --typescript, apollo-client, Graphql

मुझे लगता है कि यह डेटा लाने और इसे प्रस्तुत करने के लिए समय या आदेश की बात है। फिर भी, मुझे इस समस्या का समाधान नहीं मिल रहा है।

त्रुटि


  1. ध्यान में न आया लेखन त्रुटि: अपरिभाषित की संपत्ति 'getBoundingClientRect' पढ़ा नहीं जा सकता।
  2. ध्यान में न आया (वादे में) लेखन त्रुटि: अपरिभाषित की संपत्ति '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" alt="Previous" />
        </S.Prev>
        <S.Next onClick={nextButton}>
          <img src="/img/icon/arrow-next.svg" alt="Next" />
        </S.Next>
      </S.Arrows>
    </S.Wrap>
  );
}

1
LeeDongHee 12 जिंदा 2021, 08:40

2 जवाब

सबसे बढ़िया उत्तर

यह जाँचने के अलावा कि वस्तुएँ मौजूद हैं या नहीं (जैसे टैगी खावरी का उल्लेख किया गया है), आप बस इसे एक समयबाह्य देने का प्रयास कर सकते हैं ताकि आप अपने डोम तत्वों को ठीक से प्रस्तुत करने के लिए दे सकें। यह कभी भी सबसे अच्छा समाधान नहीं है, लेकिन यह कुछ ऐसा है जो आपकी स्क्रिप्ट को जल्दी से काम कर सकता है।

(टैगी के समाधान का उपयोग करने जा रहे हैं)

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
1
Kais Ben Daamech 14 जिंदा 2021, 12:12

ये कोशिश करें:

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
1
Taghi Khavari 14 जिंदा 2021, 12:04