【问题标题】:How to pass data got from useEffect down a component tree(got undefined)如何将 useEffect 中的数据向下传递到组件树(未定义)
【发布时间】: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?
}
【问题讨论】:
标签:
reactjs
react-hooks
use-effect
ref
use-ref
【解决方案1】:
原因是当你先这样声明它时,它的值默认是未定义的
let buttonSearchRefOffsetLeftValue;
然后,它将首先将此值传递给Search 组件在运行Header 的useEffect。这就是为什么你会得到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>;
}