I have a PaymentWidgetFooter
component with three buttons.
const PaymentWidgetFooter = React.forwardRef((props, ref) => {
return(
<div ref={ref}>
<button className={`...`} onClick={() => props.setActiveView(1)} />
<button className={`...`} onClick={() => props.setActiveView(2)} />
<button className={`...`} onClick={() => props.setActiveView(3)} />
</div>
);
}
Its props consist of a setActiveView()
function that the component calls and supplies with a number between 1-3 (inclusive) as a parameter.
<NewPaymentWidgetFooter ref={footerRef} setActiveView={() => setActiveView()} />
Once this happens, a useEffect
hook notices the change in the state variable of the parent component and triggers a updateSubviewStyles()
function which updates a dictionary that is supplied to other views to set their absolute position.
useEffect(() => {
updateSubviewStyles()
}, [activeView])
function updateSubviewStyles() {
setSubviewStyle(prevState => ({
...prevState,
1: {
...prevState[1],
left: (1 - activeView) * viewOneRef.current.clientWidth
},
2: {
...prevState[2],
left: (2 - activeView) * viewOneRef.current.clientWidth
},
3: {
...prevState[3],
left: (3 - activeView) * viewOneRef.current.clientWidth
}
}))
}
activeView
is the state variable that the setActiveView()
function changes and viewOneRef
is a reference to a div that's always rendered but may be hidden due to overflow-hidden
(and has absolute
position).
The challenge I'm dealing with is that clicking on any of the three buttons causes the subviewStyle
dictionary to contain left: NaN
values for all three children.
Confusingly, if I hardcode a value that gets called when NewPaymentWidgetFooter
calls the setActiveView
like below:
<NewPaymentWidgetFooter ref={footerRef} setActiveView={() => setActiveView(2)} />
then everything works fine and subviewStyle
contains appropriate values for the left
keys (e.g., left: 424
).
Why does the dynamic option not work when hardcoding a parameter to pass back does?
CodePudding user response:
The setActiveView
prop value you pass to NewPaymentWidgetFooter
is () => setActiveView()
, which will always call setActiveView
without any parameters. If you pass it a function that calls setActiveView
with its parameter, like this
<NewPaymentWidgetFooter ref={footerRef} setActiveView={(n) => setActiveView(n)}/>
it should use the value you pass to the callback.