依存関係の状態が変化していないにもかかわらず useEffect がトリガーされるようです?
P粉946336138
2023-08-15 16:21:30
<p>React プロジェクトでカルーセル コンポーネントを構築しようとしています。実際には、DOM を直接変更するのではなく、Refs を使用して純粋な JS で書かれた既存のカルーセル コンポーネントを活用しようとしています。シーケンス内の最初のスライドを現在のスライドとして (className current-slide で) マークしてカルーセルを初期化しようとすると、問題が発生します。このアクションを、{topMovies} が依存関係である useEffect フックに置きます。 {topMovies} は prop 経由でカルーセル コンポーネントに渡されるオブジェクトの配列であるため、topMovies が変更される (つまりロードされる) と、useEffect が実行される必要があります。これは機能します。ロード後、カルーセルの最初のスライドにはクラス名「current-slide」が付けられます。 </p>
<p>ただし、2 番目のコード (nextSlide と moveToSlide) は、次のスライドを選択する関数の始まりです。トラック Ref (つまり、すべてのスライドのコンテナ) を関数に渡すと、className が「current-slide」の子要素が選択され、その className が削除されるようになります。これも機能しますが、少し遅れて (~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 slides = Array.from(trackRef.current.children);
slides[0].classList.add('現在のスライド'); //最初のスライドを表示としてマークします
const slideWidth = slides[0].getBoundingClientRect().width;
const setSlidePosition = (スライド, インデックス) => {
slide.style.left = slideWidth * インデックス 'px';
}
slides.forEach(setSlidePosition); // スライドを並べて配置します
setIsLoading(false);
}
}, [トップムービー]);
//ボタンの機能
const moveToSlide = (currentSlide, targetSlide) => {
//trackRef.current.style.transform = 'translateX(-' targetSlide.style.left ')';
currentSlide.classList.remove('現在のスライド');
//targetSlide.classList.add('現在のスライド');
}
const updateDots = () => {
}
const 応答Btns = () => {
}
const prevSlide = (e) => {
}
const nextSlide = (e) => {
const currentSlide = trackRef.current.querySelector('.current-slide');
const nextSlide = trackRef.current.children.nextElementSibling;
moveToSlide(currentSlide, nextSlide);
}
戻る (
<div className="カルーセル">
<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.map((映画) => (
<li className="カルーセル_スライド">
<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(() => {
return <button className="carousel_indicator"></button>
})}
</div>
</div>
);
}</pre>
<p>最初に考えたのは、何らかの理由で className を変更すると useEffect が起動するということでしたので、isLoading 条件を含む if ステートメントを追加しました。しかしそれはうまくいかなかったので、このバグは useEffect フックに起因するものではないと思います。 </p>
<p>これには非常に混乱していますが、Refs を使用するのはこれが初めてなので、非常に明らかな何かを見落としている可能性は十分にあります。助けてくれてありがとう! </p>
React を使用して作成された DOM と、純粋な Javascript を使用して操作された DOM が混在しています。これはできません。DOM/VDOM 関係が壊れるだけです。
React のように動作するようにコンポーネント全体を移動することを避けたい場合は、空の要素で Ref を使用するだけで、コンポーネントのマウントとアンマウントの利点が得られるという利点があります。
その後、JavaScript コードをほとんどコピーして貼り付け、すべてを
###例えば:###useEffect
内に配置するだけです。以下では 2 つのボタンを作成しました。1 つは完全に React によって制御され、もう 1 つは JS によって制御されます。ボタンをクリックすると、
pink-buttonクラスが切り替わるだけです。 また、ボタンの順序を反転するチェックボックスを配置して、JS バージョンの状態が破損していないことを再レンダリングで表示します。これを実行するときは、必ず
key
属性を使用して React を実行できるようにします。同じコンポーネントであることがわかります。ここでの主なポイントは、React がこのボタンに干渉しなくなり、完全にユーザーの責任になることを示すことです。 React と純粋な JS を組み合わせる方法を理解するのに役立つことを願っています。リーリー リーリー リーリー