簡體   English   中英

反應焦點 useRef 僅適用於刷新

[英]React focus useRef only working on refresh

我正在使用<NavLink />直接導航到特定組件。 我認為這是問題所在 - 但問題是:

當路由完成並且組件呈現時,我試圖讓一個元素聚焦。 我有一些工作的現有方法 - 滾動工作(即,我想要聚焦的元素靠近底部並且自動滾動工作。但是,焦點框不存在)。 但是,當我刷新時,它會按需要工作 - 焦點具有滾動到功能,並且元素周圍有一個突出顯示的框。

我不確定問題是什么,但我認為這是組件從<NavLink />獲取其初始渲染的事實。

這是我使用焦點的方式:

import React, { useEffect, useRef } from "react";

const Focus = () => {
  const focusRef = useRef(null);

  useEffect(() => {
    if (focusRef && focusRef.current) {
      focusRef.current.focus();
    }
  }, [focusRef.current]);

  return (
    <React.Fragment>
      <h1 tabIndex="-1" ref={focus}>
        Focus Here
      </h1>
    </React.Fragment>
  );
};

任何幫助是極大的贊賞!

您面臨的問題是更改 ref 不會觸發渲染。 您正在使用focusRef.current作為useEffect鈎子的依賴項,但實際上,當focusRef的當前值發生變化時,它不一定會觸發效果,它只是改變了 ref 而已。 因此,您需要其他東西來觸發重新渲染,並且當發生這種情況時,會檢測到focusRef.current的更改並且可以重新運行效果。 如果focusRef.current永遠不會改變,那么效果只會在組件掛載時觸發(這就是它在刷新時起作用的原因)。

您可能使用了錯誤的工具來完成這項工作。 問問自己你想要組件來響應什么。 換位置? 然后,您需要根據位置更改而不是參考來運行效果。

const focusRef = useRef()
const location = useLocation()

useEffect(() => {
  if (location.pathname === '/my-url') {
    focusRef.current.focus()
  }
}, [location])

像這樣的東西會觸發每次location變化的效果,然后,在效果內部,您可以將條件放入路徑名中。

ref 是對具有單個屬性的對象的引用 - current 設置當前屬性不會更改對象,也不會導致重新渲染。

為了避免這種情況,您可以使用useState來保存 ref。 react 中的 ref 也可以是一個函數。 setFocusRef傳遞給組件,該組件將在渲染后立即調用它。 這會將focusRef設置為指向相關的 DOM 元素,並導致重新渲染。 focusRef的更改值將觸發useEffect ,並且由於focusRef現在不為null ,因此將調用focusRef.focus

 const { useState, useEffect } = React; const Focus = () => { const [focusRef, setFocusRef] = useState(null); useEffect(() => { if(!focusRef) return; focusRef.focus(); }, [focusRef]); return ( <h1 tabIndex="-1" ref={setFocusRef}> Focus Here </h1> ); }; ReactDOM.render( <Focus />, root )
 <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <div id="root"></div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM