React'te görünüme kaydır
İki farklı olan basit bir tepki uygulaması yapıyorum div's..
Seçilmiş giriş ve seçilen liste ile bir
<div id="container">
<div className="_2iA8p44d0WZ">
<span className="chip _7ahQImy">Item One</span>
<span className="chip _7ahQImy">Item Two</span>
<span className="chip _7ahQImy">Item Three</span>
<span className="chip _7ahQImy">Item Four</span>
<span className="chip _7ahQImy">Item Five</span>
<input
type="text"
className="searchBox"
id="search_input"
placeholder="Select"
autoComplete="off"
value=""
/>
</div>
</div>
Başka seçilen seçeneği aşağı listeler fieldset,
<div>
{selectedElements.map((item, i) => (
<div key={i} className="selected-element" ref={scrollDiv}>
<fieldset>
<legend>{item}</legend>
</fieldset>
</div>
))}
</div>
Bu çözüme dayanarak createRef, seçili öğeye şöyle ekledim:
<div key={i} className="selected-element" ref={scrollDiv}>
</div>
Ardından, DOM öğelerini almak için Javascript sorgu yöntemlerini kullandım,
const chipsArray = document.querySelectorAll("#container > div > .chip");
Tüm öğelere tıklama olayı dinleyicisi eklendi,
chipsArray.forEach((elem, index) => {
elem.addEventListener("click", scrollSmoothHandler);
});
Sonra scrollSmoothHandlerbeğen,
const scrollDiv = createRef();
const scrollSmoothHandler = () => {
console.log(scrollDiv.current);
if (scrollDiv.current) {
scrollDiv.current.scrollIntoView({ behavior: "smooth" });
}
};
Ancak bu beklendiği gibi çalışmıyor.
Gereksinim:
first divİçindeki herhangi bir öğeye tıklandığında , ilgili alan kümesinin smooth scrolledbaşka bir div içine girmesi gerekir .
Ör: Kullanıcı öğesi tıklarsanız Item Fouraltında<div id="container"> ... <span className="chip _7ahQImy">Item Four</span> ... </div>
daha sonra ilgili alan kümesinin içine kaydırılması gerekir. Burada göstergeli alan kümesi Item Four..
Ben de js dom sorgu yöntemlerini react üzerinde yapmayı düşünüyorum ve bu bir tepki uygulama şekli değil gibi görünüyor. Herhangi biri, seçilen öğeye tıklandığında ilgili bir alan kümesine kaydırmanın sonucunu elde etmeme yardımcı olabilir mi?
Yanıtlar
Konu
React.createRefgerçekten sadece sınıf tabanlı bileşenlerde geçerlidir. İşlevsel bir bileşen gövdesinde kullanılırsa, ref her oluşturma döngüsünde yeniden oluşturulur.onClickDinleyicileri DOM öğelerine eklemek için DOM sorgu seçici kullanmayın . Bunlar dışarıda canlı tepki verir ve bellek sızıntınız olmaması için bunları temizlemeyi (yani kaldırmayı) hatırlamanız gerekir. React'inonClickpervanesini kullanın .- Ne zaman
selectedElementseşleştirilir Eklemek aynı sonuncusu seti UI alır biridir, böylece her elemana ref.
Çözüm
- Kullanım
React.useRefsen görünümüne kaydırmak istediğiniz her öğe eklemek için ref tepki fonksiyonel bileşen vücutta bir dizi saklamak için. - Takın
scrollSmoothHandlerdoğrudan herspanbireyinonClickpervane. - 1.'de oluşturulan ref dizisindeki her bir referansı, kaydırmak istediğiniz her eşlenen alan kümesine ekleyin.
Kod
import React, { createRef, useRef } from "react";
import { render } from "react-dom";
const App = () => {
const selectedElements = [
"Item One",
"Item Two",
"Item Three",
"Item Four",
"Item Five"
];
// React ref to store array of refs
const scrollRefs = useRef([]);
// Populate scrollable refs, only create them once
// if the selectedElements array length is expected to change there is a workaround
scrollRefs.current = [...Array(selectedElements.length).keys()].map(
(_, i) => scrollRefs.current[i] ?? createRef()
);
// Curried handler to take index and return click handler
const scrollSmoothHandler = (index) => () => {
scrollRefs.current[index].current.scrollIntoView({ behavior: "smooth" });
};
return (
<div>
<div id="container">
<div className="_2iA8p44d0WZ">
{selectedElements.map((el, i) => (
<span
className="chip _7ahQImy"
onClick={scrollSmoothHandler(i)} // <-- pass index to curried handler
>
{el}
</span>
))}
<input
type="text"
className="searchBox"
id="search_input"
placeholder="Select"
autoComplete="off"
value=""
/>
</div>
</div>
<div>
{selectedElements.map((item, i) => (
<div
key={i}
className="selected-element"
ref={scrollRefs.current[i]} // <-- pass scroll ref @ index i
>
<fieldset>
<legend>{item}</legend>
</fieldset>
</div>
))}
</div>
</div>
);
};
2.Çözüm
Eğer herhangi unsurları güncelleştiremezsiniz yana divolan id="container"ve tüm onClickişleyicileri DOM sorgulama yoluyla bağlanmaları gerekir, hala bir Körili kullanabilir scrollSmoothHandlergeri arama ve kapsamı bir dizin içine alın. İlk oluşturmadan sonrauseEffect DOM'u sorgulamak için bir kancaya ihtiyacınız olacak, böylece aralıklar monte edilmiş olacak ve bir "yüklü" durumu depolamak için bir kancaya ihtiyacınız olacak. Durumu üzerinde rerender ve yeniden içine alın tetiklemek için gerekli olan olarak geri arama.useStatescrollRefsscrollSmoothHandler
const App = () => {
const selectedElements = [
"Item One",
"Item Two",
"Item Three",
"Item Four",
"Item Five"
];
const [loaded, setLoaded] = useState(false);
const scrollRefs = useRef([]);
const scrollSmoothHandler = (index) => () => {
scrollRefs.current[index].current.scrollIntoView({ behavior: "smooth" });
};
useEffect(() => {
const chipsArray = document.querySelectorAll("#container > div > .chip");
if (!loaded) {
scrollRefs.current = [...Array(chipsArray.length).keys()].map(
(_, i) => scrollRefs.current[i] ?? createRef()
);
chipsArray.forEach((elem, index) => {
elem.addEventListener("click", scrollSmoothHandler(index));
});
setLoaded(true);
}
}, [loaded]);
return (
<div>
<div id="container">
<div className="_2iA8p44d0WZ">
<span className="chip _7ahQImy">Item One</span>
<span className="chip _7ahQImy">Item Two</span>
<span className="chip _7ahQImy">Item Three</span>
<span className="chip _7ahQImy">Item Four</span>
<span className="chip _7ahQImy">Item Five</span>
<input
type="text"
className="searchBox"
id="search_input"
placeholder="Select"
autoComplete="off"
value=""
/>
</div>
</div>
<div>
{selectedElements.map((item, i) => (
<div key={i} className="selected-element" ref={scrollRefs.current[i]}>
<fieldset>
<legend>{item}</legend>
</fieldset>
</div>
))}
</div>
</div>
);
};