2
votes

I'm currently playing around with ReactJS' PureComponent. I have a simple component which just shows some text inside nested PureComponents:

export class Test extends React.Component<ITestProps> {
    componentDidMount(): void {
        window.setInterval(() => this.forceUpdate(), 1500);
    }

    private readonly extraSmall = { size: 10 };

    render(): JSX.Element {
        console.log("render Login");
        return (
            <Bootstrap.Container fluid={true}>
                <Bootstrap.Row>
                    <Bootstrap.Col xs={this.extraSmall}>
                        RENDERED!
                    </Bootstrap.Col>
                </Bootstrap.Row>
            </Bootstrap.Container>
        );
    }
}

I've exptected that the render would only be called once on each component. Container, Row and Col are all PureComponents. However, they all got called once every 1.5 seconds and I don't get the point why.

What I have understood from the docs is, that even if the parent is updated during forceUpdate(), each child will call the shouldComponentUpdate which should return false for each child of Test or at least Container.

But in console is see render Login, render Container, render Row and render Col. But Container's props or state did not change. So why is there a re-render happening?

From the docs:

Calling forceUpdate() will cause render() to be called on the component, skipping shouldComponentUpdate(). This will trigger the normal lifecycle methods for child components, including the shouldComponentUpdate() method of each child. React will still only update the DOM if the markup changes.

So even if this component does not make any real-life sense, it should not re-render at least Row and Col.

1
maybe "forceUpdate" has priority over shouldComponentUpdate. You can look the original reactjs code about forceUpdateJoao Polo
From the docs it says this about forceUpdate(): This will trigger the normal lifecycle methods for child components, including the shouldComponentUpdate()KingKerosin
To debug it further I'd create a tiny component with a custom sCU method and put a breakpoint inside. Then I'd see whether it's called at all and what happens if I return false.zerkms
Should you be using this.forceUpdate.bind(this) when setting the interval? It's getting called without this. Not sure if it's relatedJuan Mendes

1 Answers

1
votes

Maybe I am too late, but I will leave this answer for other users. The reason is you are using forceUpdate which ignores shouldComponentUpdate.

The reason of forceUpdate existence is to make component re-render again and again ignoring props or state update, because sometimes it is needed.

Docs reference: https://reactjs.org/docs/react-component.html#forceupdate