React:警告:不能给函数组件提供参考。尝试访问此 ref 将失败。你的意思是使用 React.forwardRef() 吗?

Posted

技术标签:

【中文标题】React:警告:不能给函数组件提供参考。尝试访问此 ref 将失败。你的意思是使用 React.forwardRef() 吗?【英文标题】:React: Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()? 【发布时间】:2021-11-11 17:43:57 【问题描述】:

我遇到了一个问题,我的代码顶部的三个useRefs()minValRefmaxValRefrange)导致了这个错误。

我已经查看了所有可用的解决方案,但我认为没有一个适合我。

我尝试将函数包装在 forwardRef() 中,但这似乎只有在 ref 被支持时才有效。

我的代码笔在下面,如果有帮助的话。谁能告诉我为什么它拒绝允许这三个useRefs()

import React,  useState, useRef, useCallback, useEffect, forwardRef  from 'react';
import Input from './RangeInputCompound';
import './RangeInputClassStyles.css';
let classnames = require('classnames');

function RangeInputComponent( min, max ) 
  const [sliderValueDisplay, setSliderValueDisplay] = useState(
    leftSliderValue: false,
    rightSliderValue: false,
  );

  const [minVal, setMinVal] = useState(min);
  const [maxVal, setMaxVal] = useState(max);
  const minValRef = useRef(null);
  const maxValRef = useRef(null);
  const range = useRef(null);

  // create a percentage from the value
  const getPercent = useCallback(
    (value) => 
      Math.round(((value - min) / (max - min)) * 100);
    ,
    [min, max]
  );

  // Set width of the range to decrease from the left side
  useEffect(() => 
    if (maxValRef.current) 
      const minPercent = getPercent(minVal);
      const maxPercent = getPercent(+maxValRef.current.value);

      if (range.current) 
        range.current.style.left = `$minPercent%`;
        range.current.style.width = `$maxPercent - minPercent%`;
      
    
  , [minVal, getPercent]);

  // Set width of the range to decrease from the right side
  useEffect(() => 
    if (minValRef.current) 
      const minPercent = getPercent(+minValRef.current.value);
      const maxPercent = getPercent(maxVal);

      if (range.current) 
        range.current.style.width = `$maxPercent - minPercent%`;
      
    
  , [maxVal, getPercent]);

  // useEffect(() => 
  //   onChange( min: minVal, max: maxVal );
  // , [minVal, maxVal, onChange]);

  function displaySliderValue(e) 
    if (e.type === 'mousedown') 
      setSliderValueDisplay(
        ...sliderValueDisplay,
        [e.target.id]: true,
      );
     else 
      setSliderValueDisplay(
        ...sliderValueDisplay,
        [e.target.id]: false,
      );
    
  

  return (
    <Input>
      <Input.Label>Revenue</Input.Label>
      <Input.RangeField
        type="range"
        name="revenue"
        id="leftSliderValue"
        min=min
        max=max
        step="5"
        value=minVal
        ref=minValRef
        onChange=(e) => 
          const value = Math.min(+e.target.value, maxVal - 1);
          setMinVal(value);
          e.target.value = value.toString();
        
        onMouseDown=displaySliderValue
        onMouseUp=displaySliderValue
        className=classnames('thumb thumb--zindex-3',  'thumb--zindex-5': minVal > max - 100 )
      ></Input.RangeField>
      <Input.RangeField
        type="range"
        name="revenue"
        id="rightSliderValue"
        min=min
        max=max
        step="5"
        value=maxVal
        ref=maxValRef
        onChange=(e) => 
          const value = Math.max(+e.target.value, minVal + 1);
          setMaxVal(value);
          e.target.value = value.toString();
        
        onMouseDown=displaySliderValue
        onMouseUp=displaySliderValue
        className="thumb thumb--zindex-4"
      />
      <Input.Slider className="slider">
        <Input.SliderTrack className="slider__track" />
        <Input.SliderRange ref=range className="slider__range" />
        sliderValueDisplay.leftSliderValue && (
          <Input.SliderValue value=minVal className="slider__left-value">
            minVal
          </Input.SliderValue>
        )
        sliderValueDisplay.rightSliderValue && (
          <Input.SliderValue value=maxVal className="slider__right-value">
            maxVal
          </Input.SliderValue>
        )
      </Input.Slider>
      <Input.LimitValueContainer>
        <Input.LimitValue>min $10k</Input.LimitValue>
        <Input.LimitValue>max $200k</Input.LimitValue>
      </Input.LimitValueContainer>
    </Input>
  );


export default RangeInputComponent;

https://codepen.io/cjmaret/pen/XWaPrBd

【问题讨论】:

【参考方案1】:

答案是,在这种情况下,“ref”指的是样式化组件,而不是 DOM 节点。我需要使用“innerRef”。

【讨论】:

以上是关于React:警告:不能给函数组件提供参考。尝试访问此 ref 将失败。你的意思是使用 React.forwardRef() 吗?的主要内容,如果未能解决你的问题,请参考以下文章

基于类的组件具有功能组件的参考警告

|React:useOutsideClick 钩子给出 forwardRef 警告信息

如何在 React Native 中使用 React.forwardRef()

React-hook-form v7 - 自定义输入警告功能组件不能被赋予参考

Material-ui Autocomplete 警告 提供给 Autocomplete 的值无效

在对计数器函数的React中使用映射函数