useRef 值在初始渲染时未定义

miv*_*ivd 7 reactjs react-leaflet

我正在用反应和反应传单制作地图。React Leaflet 有一个名为 FeatureGroup 的类,我想在第一次渲染时使用 React 中的 useRef 钩子访问该类,然后访问 useEffect 函数中的值。然而,在初始渲染时,ref 未定义(markerRef.current 返回 null)。仅当我对代码进行任何类型的更改、保存并重新加载 React 应用程序后,它才会获取值

你能告诉我我做错了什么以及如何使markerRef.current在初始渲染上不为空吗?

请在下面找到该组件的缩写代码:

import {useRef} from 'react';
import {FeatureGroup, //... } from 'react-leaflet';

const MapView = ({breweries}) => {
  const markerGroupRef = useRef(null);
  //...
  useEffect(() => {
    if(markerGroupRef.current) {
      //here I want to access a method called getBounds() which is in the markerGroupRef.current object 
      //but markerGroupRef.current has null value and so it doesn't execute
      //when making a save change and react app reloads it has the FeatureGroup class as value as expected
      console.log(markerGroupRef.current)
    }
  }, [markerGroupRef])
  //...
  return (
            <FeatureGroup ref={markerGroupRef}>
              {breweries && breweries.map(brewery => <Brewery key={breweries.indexOf(brewery)} brewery={brewery}/>)}
              {breweryStore && breweryStore.searchLocation &&  <LocationMarker markerPosition={{lat: breweryStore.searchLocation.lat, lng: breweryStore.searchLocation.lon}}/>}
            </FeatureGroup>
    );
  }
Run Code Online (Sandbox Code Playgroud)

rub*_*buc 9

useRef创建的引用不会触发组件重新渲染。因此您创建的 useRef 挂钩将永远不会执行。此外,由于您将 ref 初始化为 null,因此在第一次渲染开始时,它将保持为 null。在第一次渲染期间,ref={markerGroupRef}onFeatureGroup将更新它,但同样不会触发另一次渲染。必须修改状态才能触发任何可能的重新渲染

\n

您可能想要使用此处所示的回调引用

\n
function MeasureExample() {\n  const [height, setHeight] = useState(0);\n\n  const measuredRef = useCallback(node => {\n    if (node !== null) {\n      setHeight(node.getBoundingClientRect().height);\n    }\n  }, []);\n\n  return (\n    <>\n      <h1 ref={measuredRef}>Hello, world</h1>\n      <h2>The above header is {Math.round(height)}px tall</h2>\n    </>\n  );\n}\n
Run Code Online (Sandbox Code Playgroud)\n

并在这里证明合理

\n
\n

请记住,useRef 在其内容更改时不会通知您。\n改变 .current 属性不会导致重新渲染。如果您想要\n在 React 将引用附加到 DOM 节点或从 DOM 节点分离时运行一些代码,\n您可能需要使用回调引用。

\n
\n


Mr.*_*bot 4

您的问题是更新引用不会使组件重新渲染,因此 useEffect 只运行一次,并且在第一次渲染时引用仍然为空。

您所描述的是正确的行为,您将需要等待重新渲染才能对引用执行任何操作。如果强制重新渲染,您将能够使用 ref.current 属性:

    const MapView = ({ breweries }) => {
        const markerGroupRef = useRef(null);
        const [refAquired, setRefAquired] = useState(false)
        //...
        useEffect(() => {
            setRefAquired(true)
        }, []);

        useEffect(()=> {
            console.log(markerGroupRef.current)
        }, [refAquired])
Run Code Online (Sandbox Code Playgroud)

这是一个粗略的演示,您应该尝试使渲染周期与其他渲染和业务逻辑相关联。