如何将 useEffect 中的数据向下传递到组件树(未定义)

Posted

技术标签:

【中文标题】如何将 useEffect 中的数据向下传递到组件树(未定义)【英文标题】:How to pass data got from useEffect down a component tree(got undefined) 【发布时间】:2021-01-28 01:07:57 【问题描述】:

我想在搜索组件中进行特定的计算。为此,我必须将在 Header 组件中获得的 buttonSearchRefOffsetLeftValue 传递给 Search 组件。我在标题中获得了所需的值。但是,在 Search 组件中,它总是未定义。无法理解这种行为。

const Header = props => 
     const buttonSearchRef = useRef(null);

     let buttonSearchRefOffsetLeftValue;

     useEffect(() => 
         buttonSearchRefOffsetLeftValue = 
         ReactDOM.findDOMNode(buttonSearchRef.current).offsetLeft;
         console.log(buttonSearchRefOffsetLeftValue); //got the value
      )

   return (
      <div ref=buttonSearchRef>He<div>
             <Search buttonSearchRefOffsetLeftValue= 
          buttonSearchRefOffsetLeftValue />
       ) 
     

 const Search = (props) => 
     console.log(props.buttonSearchRefOffsetLeftValue)//got undefined WHY?
 

【问题讨论】:

【参考方案1】:

原因是当你先这样声明它时,它的值默认是未定义的

 let buttonSearchRefOffsetLeftValue;

然后,它将首先将此值传递给Search 组件运行HeaderuseEffect。这就是为什么你会得到undefined。 之后,当 DOM 完全渲染后,附加了 ref,useEffect 运行并更新 buttonSearchRefOffsetLeftValue,但这 不是 React 状态或道具。因此,它不会在Search 中更新props.buttonSearchRefOffsetLeftValue,导致它仍然保持未定义。

对此的快速解决方法是将buttonSearchRefOffsetLeftValue 置于一个状态

export const Header = (props) => 
  const buttonSearchRef = useRef(null);

  const [ buttonSearchRefOffsetLeftValue, setButtonSearchRefOffsetLeftValue] = useState(null);

  useEffect(() => 
      setButtonSearchRefOffsetLeftValue(ReactDOM.findDOMNode(buttonSearchRef.current).offsetLeft);
      console.log('head', buttonSearchRefOffsetLeftValue); //got the value
  );

  return (<div>
    <div ref=buttonSearchRef>He</div>
    <Search buttonSearchRefOffsetLeftValue=buttonSearchRefOffsetLeftValue/></div>);
  

现在您的Search 组件应该记录控制台两次,第二次打印出值。

【讨论】:

【参考方案2】:

你可能已经注意到了。控制台日志将按如下顺序打印:

未定义

0

这意味着useEffect 总是在return 函数之后被调用。 我建议你应该有buttonSearchRefOffsetLeftValue 的状态来传递它的子组件。将您的变量依赖项放入useEffect 中的buttonSearchRefOffsetLeftValue 将生效。

我的演示:

const Search = (props) => 
    console.log('value'+ props.buttonSearchRefOffsetLeftValue)//got undefined WHY?
    return <div/>


const Header = props => 
    const buttonSearchRef = useRef(null);

    const [buttonSearchRefOffsetLeftValue, setButtonSearchRefOffsetLeftValue] = useState(null);

    useEffect(() => 
        let buttonSearchRefOffsetLeftValue = ReactDOM.findDOMNode(buttonSearchRef.current).offsetLeft;
        setButtonSearchRefOffsetLeftValue(buttonSearchRefOffsetLeftValue);
        console.log(buttonSearchRefOffsetLeftValue); //got the value
    , [
        //put some dependencies will effect your buttonSearchRefOffsetLeftValue
    ])

    return <div>
            <div ref=buttonSearchRef>He</div>
            <Search buttonSearchRefOffsetLeftValue=buttonSearchRefOffsetLeftValue />
        </div>;

【讨论】:

添加状态让一切变得不同!谢谢!:)

以上是关于如何将 useEffect 中的数据向下传递到组件树(未定义)的主要内容,如果未能解决你的问题,请参考以下文章

VueJS - 将插槽和作用域插槽向下传递给子模板中的组件

从服务器获取数据并将值传递给 React 中的子组件(useEffect、useFetch..)

如何将状态传递给路由器组件?

如何在数组依赖中正确使用 useEffect 挂钩。我从 redux 商店传递了状态,但我的组件仍然无限渲染

反应:仅将主体类添加到 useEffect 挂钩中的某些组件?

useMemo, useCallback, useEffect 三者区别