Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get how many times the component was rendered #135

Closed
Belco90 opened this issue Aug 3, 2019 · 3 comments
Closed

Get how many times the component was rendered #135

Belco90 opened this issue Aug 3, 2019 · 3 comments
Labels
enhancement New feature or request

Comments

@Belco90
Copy link
Member

Belco90 commented Aug 3, 2019

Describe the feature you'd like:

I would like to get inside result a property with number of times the component was rendered. It could be called renderCount.

The only drawback I can think about is performance issues, but I don't think a counter is a problem.

Suggested implementation:

One option could be wrapping the setValue passed to TestHook so it increase an external count each time than setValue is called.

Another option could be to pass an utils object to TestHook as a children with properties setValue and increaseCount so TestHook itself is in charge of increasing the count before calling children.setValue.

I think it's important increasing the count even if it fails, as in the end the component was triggered to be rendered.

Not really sure about where to init the count. Maybe a ref inside TestHook?

Describe alternatives you've considered:

I'm trying to test a hook that returns a function to force a component to be re-rendered. I've tried to pass the count from outside but 1) I can't pass inner components, only outer (the wrapper) or 2) pass component prop but this is not possible.

I could build my own testing component with react-testing-library that calls the function returned by the hook when a button is clicked or something like that but I only have this library available in the project for now and I don't want to install RTL only for this test.

I can't think other way to test the hook I described.

Teachability, Documentation, Adoption, Migration Strategy:

I think is useful to get how many times the component was rendered for other purposes too: checking performance issues or memoized behaviors.

Would be easy to include in the docs, just adding a new element to renderHook Result section explaining what do you get for renderCount property.

@Belco90 Belco90 added the enhancement New feature or request label Aug 3, 2019
@Belco90 Belco90 mentioned this issue Aug 3, 2019
5 tasks
@Belco90
Copy link
Member Author

Belco90 commented Aug 3, 2019

I just figured out how this can be implemented and created proper PR #136

@mpeyper
Copy link
Member

mpeyper commented Aug 9, 2019

Closing for now. See comment in the PR for details.

@TheNotary
Copy link

I'm using useContext for the first time. Things have gotten pretty complex with it due to my noviceship and I needed a way to add a simple count to my <LoginPage /> which is really just a testbed page at this point specific to Logins and the userContext. Because of interactions between my javascript Proxy object and setState, I was getting ridiculous amounts of re-rendering taking place and odd bugs related to creating proxies of proxies.

I thought it was going to be an excruciating challenge doing this in a react environment, but it wound up being really easy. I just render a let variable that's instantiated outside of my component, and incremented within the component. Now I'll know if I re-introduce the bug because the number will make really large jumps as I interact with the page.

let renderCount = 0;
export default function LoginPage() {
    renderCount++;
    const userContext = useContext(UserContext);
.
.
.
return (
    <>
        ....
        <div>renderCount: {renderCount}</div>
    </>
  );
}
}

I remarked on my test setup here 3 years ago when I last had time to explore react. It's probably pretty out of date, but the gist is captured below:

(LoginPage.test.js)

import { render, fireEvent, screen } from "../../../tools/test-utils";


test("I can go from logged out to logged in and back with the power of userContext", () => {
    const {getByText } = render(<LoginPage />, {
      rootReducer: rootReducer,
    });

    expect(getByText("Logged Out"))

    const log_in_button = getByText(/change to logged_in/i)
    const pending_button = getByText(/change to pending/i)
    const log_out_button = getByText(/change to logged_out/i)


    fireEvent.click(log_in_button)
    expect(getByText("Logged In"))
});

(test-utils.js)

/* eslint-disable */
import React, { useEffect } from "react";
import { render as rtlRender } from "@testing-library/react";
import { configureStore } from "@reduxjs/toolkit";
import { Provider } from "react-redux";
import { BrowserRouter as Router } from "react-router-dom";
import { UserContextProvider } from '../src/app/UserContextProvider';


function render(ui, { rootReducer, ...renderOptions } = {}) {
  const store = configureStore({ reducer: rootReducer });
  const azureAuthMock = {
    initApp: () => {},
    signInMicrosoft: () => {},
    signOutMicrosoft: () => {},
  }

  function Wrapper({ children }) {

    return (
      <Provider store={store}>
        <UserContextProvider azureAuth={azureAuthMock}>
          <Router>
            {children}
          </Router>
        </UserContextProvider>
      </Provider>
    );
  }

  return rtlRender(ui, { wrapper: Wrapper, ...renderOptions });
}

// re-export everything
export * from "@testing-library/react";

// override render method
export { render };

I couldn't figure out how to merge "hooks" into render, but am open to alternative approaches to how modern testing would be done with react to keep an eye on these kinds of excess-render bugs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants