Javascript 在react中滚动到视图
我正在制作一个简单的react应用程序,其中有两个不同的Javascript 在react中滚动到视图,javascript,reactjs,scroll,Javascript,Reactjs,Scroll,我正在制作一个简单的react应用程序,其中有两个不同的div 一个带有选择输入和选择列表 <div id="container"> <div className="_2iA8p44d0WZ"> <span className="chip _7ahQImy">Item One</span> <span className="chip _7
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>
基于,我已将createRef
添加到所选元素,如
<div key={i} className="selected-element" ref={scrollDiv}>
</div>
将click事件侦听器添加到所有元素,如
const chipsArray = document.querySelectorAll("#container > div > .chip");
chipsArray.forEach((elem, index) => {
elem.addEventListener("click", scrollSmoothHandler);
});
然后scrollSmoothHandler
like
const scrollDiv = createRef();
const scrollSmoothHandler = () => {
console.log(scrollDiv.current);
if (scrollDiv.current) {
scrollDiv.current.scrollIntoView({ behavior: "smooth" });
}
};
但这并不像预期的那样有效
要求:
单击第一个div
中的任何项,则其相关字段集需要在另一个div中平滑滚动
例如:
如果用户单击下面的元素项目4
。。。第四项代码>
然后,需要将相关字段集滚动到。此处是带有图例的字段集,如项目4
我认为在react上使用JSDOM查询方法似乎不是一种react实现方式。请任何人帮助我实现在点击所选项目时滚动到相关字段集的结果
问题
React.createRef实际上仅在基于类的组件中有效。如果在功能组件主体中使用,则将在每个渲染周期重新创建ref
不要使用DOM查询选择器将onClick
侦听器附加到DOM元素。这些活动在外部进行反应,您需要记住清理它们(即移除它们),以避免内存泄漏。使用React的onClick
prop
映射selectedElements
时,您会将相同的引用附加到每个元素,因此最后一个集合就是您的UI获得的集合
解决方案
在功能组件主体中使用React.useRef
,存储要附加到要滚动到视图中的每个元素的React ref数组
将scrollSmoothHandler直接连接到每个span
的onClick
属性
从1中创建的ref数组中附加每个ref。要滚动到的每个映射字段集
代码
对不起,我昨天很晚才看到你的消息,直到不久前,我今天大部分时间都很忙。我已经回答了下面的问题,我认为这是解决您的问题的方法。@DrewReese,再次抱歉打扰您,但现在这里的问题不同了,@DrewReese,请告诉我如何处理上面发布的问题。。我接收的数据是一个数组,我将迭代并显示在每一行上,每一行都有一个保存按钮。。我需要将每一行的数据作为一个对象提交,比如,{ContactMode:1}
…非常感谢Reese,请您查看下面的评论。。我无法修改此行onClick={scrollSmoothHandler(I)}
在我的real ap中,因为我正在使用一个库。因此,一般来说,我需要在加载DOM后添加click事件,但我需要动态地添加它,因为它们不是real app中的硬编码jsx。我只需要在第一个div/span标记中得到帮助,因为在第二节中包含fieldset,你可以修改任何东西,而且没有问题。@Undefined啊,我明白了。让我看看我能想出什么。正如我正确理解的那样,您不能修改id=“container”
div中的跨距和scrollSmoothHandler
的附加,ref创建需要基于DOM中查询的内容进行动态?感谢Reese,最终的要求是,如果我单击任何选定的芯片(关闭图标除外)在该库中,则需要滚动选定项的字段集。。因此,我用该库的简单代码关闭了codesandbox,我无法单独修改第一个div代码。。因此,只有我在问题代码沙盒中使用DOM创建了click事件处理程序。。我很抱歉没有提及。。当然,请仔细检查场景,并让我知道更新的解决方案。。
const scrollDiv = createRef();
const scrollSmoothHandler = () => {
console.log(scrollDiv.current);
if (scrollDiv.current) {
scrollDiv.current.scrollIntoView({ behavior: "smooth" });
}
};
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>
);
};
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>
);
};