Paul
Paul

Reputation: 1441

subcomponent is re-rendering on prop change, but prop is a function

I am using react 16.12.0 with functional components and typescript 3.7.2.

Problem: My subcomponent B is re-rendering every time when a variable is changed in component A, although these variables are not passed to the subcomponentB. I am only passing a function from componentA to componentB.

I have two components (Component A and component B). Component A is the parent of component B. Component A is holding one variable and a function. The function is delivered to component B but NOT the value. In component A there is also a timer running, changing the variable "value" in X-seconds.

Component A:
const [value, setValue] = React.useState<number>(1);
function timer(): void {
    //Running all 8 seconds
    setValue(value => value + 1);
}

function doSomethingInComponentA(): void {
    //some logic, like send some data to the server
    //or change the value
}

Now the subcomponent B:

interface Props {
    doSomethingInComponentA: Function;
}

const ComponentB: React.FC<Props> = (props) => {


    useEffect(() => {
        //every time when the timer changes the value in component A useEffect will be fired.
        console.log("Has something changed?);
    });

    function doSomething(): void {
        props.doSomethingInComponentA();
    }

    return (
        <>
            //ERROR - THIS COMPONENT WILL BE RE-RENDERER EVERY TIME WHEN THE TIMER IS CHANGING THE VALUE
            Button onClick=doSomething() CLICK ME;
        </>
    );
};

export default ComponentB;

Now when the timer-function is changing the variable value, a rerendering is fired in the subcomponentB, although only the function doSomethingInComponentA is passed to the subcomponent.

Why do we have this behavior? In my understand the re-rendering is only fired when the variable-value would be passed to subcomponentB. The function is never changing, it is a function, not a variable.

Hopefully I could explain it correctly.

Upvotes: 0

Views: 92

Answers (1)

Vencovsky
Vencovsky

Reputation: 31625

Your question is very confusing but try using useCallback in the function your are passing to the child component.

const yourFunction = React.useCallback(
  () => {
    // your function body
  },
  [a, b], // only the values that will change and make yourFunction change
);

The function is never changing, it is a function, not a variable

Because your parent component is a functional component, the function will be recreated on every parent render, which will make the child component render.

Upvotes: 2

Related Questions