Nampaknya useEffect dicetuskan walaupun keadaan kebergantungan tidak berubah?
P粉946336138
2023-08-15 16:21:30
<p>Saya cuba membina komponen karusel dalam projek React saya - Saya sebenarnya cuba memanfaatkan komponen karusel sedia ada yang ditulis dalam JS tulen, menggunakan Refs untuk menjadikannya berfungsi dalam React, dan bukannya mengubah suai terus DOM. Saya menghadapi masalah apabila saya cuba memulakan karusel dengan menandakan slaid pertama dalam jujukan sebagai slaid semasa (dengan slaid semasa className). Saya meletakkan tindakan ini dalam cangkuk useEffect di mana {topMovies} adalah kebergantungan. {topMovies} ialah tatasusunan objek yang dihantar ke komponen karusel melalui prop, jadi apabila topMovies berubah (iaitu dimuatkan), useEffect harus dijalankan. Ini berfungsi - selepas memuatkan, slaid pertama dalam karusel diberi nama kelas 'slaid semasa'. </p>
<p>Walau bagaimanapun, sekeping kod kedua (nextSlide dan moveToSlide) ialah permulaan fungsi yang memilih slaid seterusnya. Hantar Rujukan trek (iaitu bekas semua slaid) ke fungsi supaya elemen anak dengan className 'current-slide' boleh dipilih dan classNamenya dialih keluar. Ini juga berfungsi - tetapi selepas kelewatan yang singkat (~1 saat) className 'current-slide' muncul semula.</p>
<pre class="brush:php;toolbar:false;">const Carouselv2 = ({topMovies}) => {
//Ruj
const trackRef = useRef();
const nextBtnRef = useRef();
const prevBtnRef = useRef();
const navDotsRef = useRef();
//Memulakan karusel apabila beban prop
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
if (Filem && setIsLoading teratas) {
slaid const = Array.from(trackRef.current.children);
slaid[0].classList.add('slaid semasa'); //Tandakan slaid pertama sebagai boleh dilihat
const slideWidth = slaid[0].getBoundingClientRect().width;
const setSlidePosition = (slaid, indeks) => {
slide.style.left = slideWidth * indeks + 'px';
}
slides.forEach(setSlidePosition); //Susun slaid bersebelahan antara satu sama lain
setIsLoading(false);
}
}, [Filem teratas]);
//Kefungsian butang
const moveToSlide = (currentSlide, targetSlide) => {
//trackRef.current.style.transform = 'translateX(-' + targetSlide.style.left + ')';
currentSlide.classList.remove('current-slide');
//targetSlide.classList.add('current-slide');
}
kemas kini constDots = () => {
}
const responsifBtns = () => {
}
const prevSlide = (e) => {
}
const nextSlide = (e) => {
const currentSlide = trackRef.current.querySelector('.current-slide');
const nextSlide = trackRef.current.children.nextElementSibling;
moveToSlide(currentSlide, nextSlide);
}
kembali (
<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((filem) => (
<li className="carousel_slide">
<img src={movie.image} alt="" />
<h2>{movie.title}</h2>
</li>
))}
</ul>
</div>
<butang onClick={(e) => nextSlide(e)}className="carousel_button carousel_button--right" ref={nextBtnRef}><FontAwesomeIcon icon={faCircleRight} size="xl" style={{ warna: "putih" }} /></button>
<div className="carousel_nav" ref={navDotsRef}>
<button className="carousel_indicator current-slide"></button>
{topMovies && Array.apply(0, Array(topMovies.length)).map(() => {
kembalikan <button className="carousel_indicator"></button>
})}
</div>
</div>
);
}</pre>
<p>Pemikiran awal saya ialah atas sebab tertentu, menukar className menyebabkan useEffect terbakar, jadi saya menambah pernyataan if dengan keadaan isLoading. Tetapi itu tidak berjaya, jadi saya tidak fikir pepijat itu datang daripada cangkuk useEffect. </p>
<p>Sangat keliru dengan ini, tetapi ini kali pertama saya menggunakan Rujukan, jadi kemungkinan besar saya kehilangan sesuatu yang sangat jelas. Terima kasih atas bantuan anda! </p>
Anda sedang mencampurkan DOM yang dibuat menggunakan React dan DOM yang dimanipulasi menggunakan Javascript tulen. Anda tidak boleh melakukan ini, ia hanya akan memutuskan hubungan DOM/VDOM.
Jika anda ingin mengelak daripada menggerakkan keseluruhan komponen untuk berfungsi seperti yang dilakukan oleh React, maka hanya gunakan Ref pada elemen kosong, faedahnya ialah anda mendapat faedah pemasangan dan nyahlekap komponen.
Kemudian anda boleh salin-tampal kod Javascript dan letakkan semuanya di dalam
useEffect
.Contohnya:
Di bawah saya telah mencipta dua butang, satu dikawal sepenuhnya oleh React dan satu lagi oleh JS, yang hanya akan menogol kelas
pink-button
apabila anda mengklik padanya. Saya juga meletakkan kotak pilihan untuk membalikkan susunan butang untuk menyebabkan pemaparan semula menunjukkan bahawa keadaan versi JS tidak dimusnahkan, pastikan anda menggunakan atributkey
semasa melakukan ini untuk memberitahu React bahawa ia adalah komponen yang sama. Perkara utama di sini adalah untuk menunjukkan bahawa React kini tidak lagi mengganggu butang ini, ia kini menjadi tanggungjawab anda sepenuhnya. Harap ini membantu anda memahami cara mencampurkan React dengan JS tulen.