찾다

 >  Q&A  >  본문

종속성 상태가 변경되지 않았는데도 useEffect가 트리거되는 것 같나요?

<p>저는 React 프로젝트에서 캐러셀 컴포넌트를 구축하려고 합니다. 실제로 DOM을 직접 수정하는 대신 Refs를 사용하여 순수 JS로 작성된 기존 캐러셀 컴포넌트를 활용하려고 합니다. 시퀀스의 첫 번째 슬라이드를 현재 슬라이드(className current-slide 사용)로 표시하여 회전식 슬라이드를 초기화하려고 하면 문제가 발생합니다. 이 작업을 {topMovies}가 종속성인 useEffect 후크에 넣었습니다. {topMovies}는 prop을 통해 캐러셀 구성요소에 전달되는 객체 배열이므로 topMovies가 변경되면(예: 로드) useEffect가 실행되어야 합니다. 이것은 작동합니다. 로딩 후 캐러셀의 첫 번째 슬라이드에는 클래스 이름 'current-slide'가 지정됩니다. </p> <p>그러나 두 번째 코드 부분(nextSlide 및 moveToSlide)은 다음 슬라이드를 선택하는 함수의 시작 부분입니다. className이 'current-slide'인 하위 요소를 선택하고 해당 className을 제거할 수 있도록 트랙 Ref(즉, 모든 슬라이드의 컨테이너)를 함수에 전달합니다. 이 방법도 작동하지만 짧은 지연(~1초) 후에 className 'current-slide'가 다시 나타납니다.</p> <pre class="brush:php;toolbar:false;">const Carouselv2 = ({topMovies}) => { //참조 const trackRef = useRef(); const nextBtnRef = useRef(); const prevBtnRef = useRef(); const navDotsRef = useRef(); //소품 로드 시 캐러셀 초기화 const [isLoading, setIsLoading] = useState(true); useEffect(() => { if (topMovies && setIsLoading) { const 슬라이드 = Array.from(trackRef.current.children); Slides[0].classList.add('current-slide'); //첫 번째 슬라이드를 표시되도록 표시 const SlideWidth = 슬라이드[0].getBoundingClientRect().width; const setSlidePosition = (슬라이드, 인덱스) => { Slide.style.left = SlideWidth * 인덱스 + 'px'; } Slides.forEach(setSlidePosition); //슬라이드를 서로 나란히 정렬 setIsLoading(false); } }, [topMovies]); //버튼 기능 const moveToSlide = (currentSlide, targetSlide) => { //trackRef.current.style.transform = 'translateX(-' + targetSlide.style.left + ')'; currentSlide.classList.remove('현재-슬라이드'); //targetSlide.classList.add('현재-슬라이드'); } const updateDots = () => { } const ResponseBtns = () => { } const prevSlide = (e) => { } const nextSlide = (e) => { const currentSlide = trackRef.current.querySelector('.current-slide'); const nextSlide = trackRef.current.children.nextElementSibling; moveToSlide(currentSlide, nextSlide); } 반품 ( <div className="carousel"> <button className="carousel_button carousel_button--left" ref={prevBtnRef}><FontAwesomeIcon icon={faCircleLeft} size="xl" style={{ color: "white" }} /></button> ; <div className="carousel_track-container"> <ul className="carousel_track" ref={trackRef}> {topMovies && topMovies.map((영화) => ( <li className="carousel_slide"> <img src={movie.image} alt="" /> <h2>{영화.제목}</h2> </li> ))} </ul> </div> <button onClick={(e) => nextSlide(e)}className="carousel_button carousel_button--right" ref={nextBtnRef}><FontAwesomeIcon icon={faCircleRight} size="xl" style={{ 색상: "흰색" }} /></button> <div className="carousel_nav" ref={navDotsRef}> <button className="carousel_indicator current-slide"></button> {topMovies && Array.apply(0, Array(topMovies.length)).map(() => { 반환 <button className="carousel_indicator"></button> })} </div> </div> ); }</pre> <p>처음에는 어떤 이유로 className을 변경하면 useEffect가 실행될 것이라고 생각하여 isLoading 조건이 있는 if 문을 추가했습니다. 그러나 그것은 작동하지 않았으므로 버그가 useEffect 후크에서 비롯된 것이라고 생각하지 않습니다. </p> <p>이 점 때문에 매우 혼란스럽습니다. 하지만 Refs를 처음 사용하는 것이므로 아주 분명한 것을 놓치고 있을 가능성이 충분히 있습니다. 도와주셔서 감사합니다! </p>
P粉946336138P粉946336138468일 전542

모든 응답(1)나는 대답할 것이다

  • P粉642436282

    P粉6424362822023-08-16 10:19:47

    React를 사용하여 만든 DOM과 순수 Javascript를 사용하여 조작한 DOM을 혼합하고 있습니다. 이렇게 하면 DOM/VDOM 관계가 깨질 뿐입니다.

    React처럼 작동하도록 전체 구성 요소를 이동하지 않으려면 빈 요소에 Ref를 사용하면 구성 요소 마운트 및 마운트 해제의 이점을 얻을 수 있다는 이점이 있습니다.

    그런 다음 Javascript 코드를 복사하여 붙여넣고 모두 안에 넣을 수 있습니다 useEffect.

    예:

    아래에는 두 개의 버튼을 만들었습니다. 하나는 React로 완전히 제어되고 다른 하나는 JS로 제어되며, 클릭하면 pink-button 클래스가 토글됩니다. 또한 JS 버전의 상태가 파괴되지 않았음을 다시 렌더링하도록 버튼 순서를 뒤집는 확인란을 배치했습니다. 이 작업을 수행할 때 key 속성을 사용하여 React가 동일한 구성 요소임을 알 수 있도록 하세요. 여기서 중요한 점은 이제 React가 더 이상 이 버튼을 방해하지 않으며 이는 전적으로 귀하의 책임임을 보여주는 것입니다. 이것이 React와 순수 JS를 혼합하는 방법을 이해하는 데 도움이 되기를 바랍니다.

    으아악 으아악 으아악

    회신하다
    0
  • 취소회신하다