Reputation: 129
I want to make a specific calculation in Search component. To do this, I have to pass a buttonSearchRefOffsetLeftValue obtained in the Header component to a Search component. I get the desired value in the Header. However in the Search component it always gets undefined. Can't understand this behavior.
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?
}
Upvotes: 0
Views: 77
Reputation: 3452
The reason is when you declare it first like this, its value will be undefined by default
let buttonSearchRefOffsetLeftValue;
Then, it will pass this value first to Search
component before the useEffect
of Header
is run. Thats why you get undefined
.
AFter that, when the DOM is fully rendered, the ref is attached, useEffect runs and update buttonSearchRefOffsetLeftValue
, but this is not a React state or props. Therefore, it not update props.buttonSearchRefOffsetLeftValue
in Search
, resulting it still keeps undefined.
A quick fix for this is to put buttonSearchRefOffsetLeftValue
in a state
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>);
}
now your Search
component should log the console twice, with the second time printing out the value.
Upvotes: 2
Reputation: 1961
You may have noticed that. Console log will print in order like:
undefined
0
This mean useEffect
always be called after return
function.
I suggest you should have state for buttonSearchRefOffsetLeftValue
to pass it child component. Put your variable dependencies will make effect to buttonSearchRefOffsetLeftValue
in useEffect
.
My demo:
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>;
}
Upvotes: 1