Home > Back-end >  Function Misbehaving When Passed Down as Prop
Function Misbehaving When Passed Down as Prop

Time:03-17

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.

  • Related