Javascript 在React中使用document.querySelector?我应该改用refs吗?怎么用?

Javascript 在React中使用document.querySelector?我应该改用refs吗?怎么用?,javascript,reactjs,ref,use-effect,js-scrollintoview,Javascript,Reactjs,Ref,Use Effect,Js Scrollintoview,我现在正在建造一个旋转木马,以回应。要滚动到各个幻灯片,我使用document.querySelector如下所示: useEffect(() => { document.querySelector(`#slide-${activeSlide}`).scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' }); }, [activeSlide])

我现在正在建造一个旋转木马,以回应。要滚动到各个幻灯片,我使用
document.querySelector
如下所示:

useEffect(() => {
    document.querySelector(`#slide-${activeSlide}`).scrollIntoView({
      behavior: 'smooth',
      block: 'nearest',
      inline: 'nearest'
    });
  }, [activeSlide]);
这是坏习惯吗?毕竟,我在这里直接访问DOM?这样做的方法是什么

编辑:完全
返回
方法

return (
    <>
      <button onClick={() => setActiveSlide(moveLeft)}>PREV</button>
      <Wrapper id="test">
        {children.map((child, i) => {
          return (
            <Slide id={`slide-${i}`} key={`slide-${i}`}>
              {child}
            </Slide>
          );
        })}
      </Wrapper>

      <button onClick={() => setActiveSlide(moveRight)}>NEXT</button>
    </>
  );
返回(
setActiveSlide(左移)}>PREV
{children.map((child,i)=>{
返回(
{child}
);
})}
setActiveSlide(右移动)}>NEXT
);
我无法回答是否使用refs的“应该”部分,除非您使用refs,否则您不需要这些
id
值,除非您将它们用于其他用途

但你可以这样做:

  • 用于创建引用

    const activeSlideRef = useRef(null);
    
  • 将其放在当前处于活动状态的
    幻灯片上

    <Slide ref={i === activeSlide ? activeSlideRef : null} ...>
    
    (我认为,
    activeSlide
    是这种效果的合理依赖。您不能使用ref,ref本身没有变化…)

  • 例如,为了方便起见,我将您的一些组件转换为
    div
    s:

    const{useffect,useRef,useState}=React;
    函数组({children}){
    const[activeSlide,setActiveSlide]=useState(0);
    const-activeSlideRef=useRef(null);
    useffect(()=>{
    如果(activeSlideRef.current){
    activeSlideRef.current.scrollIntoView({
    行为:“平滑”,
    街区:“最近的”,
    内联:“最近的”
    });
    }
    },[activeSlide]);
    const moveLeft=Math.max(0,activeSlide-1);
    const moveRight=Math.min(childrence.length-1,activeSlide+1);
    返回(
    setActiveSlide(左移)}>PREV
    {children.map((child,i)=>{
    const active=i==activeSlide;
    返回(
    {child}
    );
    })}
    setActiveSlide(右移动)}>NEXT
    );
    }
    ReactDOM.render(
    幻灯片0
    幻灯片1
    幻灯片2
    幻灯片3
    幻灯片4
    幻灯片5
    幻灯片6
    幻灯片7
    幻灯片8
    幻灯片9
    ,
    document.getElementById(“根”)
    );
    
    。幻灯片{
    高度:4em;
    垂直对齐:中间对齐;
    文本对齐:居中;
    }
    #试验{
    溢出:滚动;
    最大高度:20em;
    }
    .主动{
    字体大小:粗体;
    颜色:蓝色;
    }
    
    
    您滑入视图的元素是否由组件渲染?是。我将编辑我的文章,包括完整的返回块非常感谢你,这是工作!你知道在第一次渲染时是否可以在这里禁用
    useffect
    ?@R.Kohlisch-我在答案的末尾添加了一个选项来演示如何做到这一点。这太神奇了,非常感谢。我希望我能对这个答案投更多的票!!REF对于获取您关心的特定DOM节点更可靠。如果有多个元素与查询匹配,特别是在元素外部有一个元素与查询匹配时,使用
    querySelector
    或类似的(
    getElementsByClass
    getElementById
    )可能会产生意外的结果。如果您正在编写一个组件,它将在许多地方多次出现,那么ref将成为一个明确的赢家。这个答案中的第2步(有条件地指定ref)绝对是天才。我已经为自定义typeahead奋斗了好几天,我只想为键盘事件调用一些自定义滚动逻辑,因为它会使鼠标滚动出错。所以需要在父对象中有一个对子对象的引用,这个解决方案非常有效。好东西。
    useEffect(() => {
        if (activeSlideRef.current) {
            activeSlideRef.current.scrollIntoView({
              behavior: 'smooth',
              block: 'nearest',
              inline: 'nearest'
            });
        }
    }, [activeSlide]);