Git Product home page Git Product logo

Comments (11)

mpeyper avatar mpeyper commented on May 20, 2024 38

Hi @DavidBabel (great name for JS dev!),

You're so close with your test. The issue is that the props are not passed through the the hook callback so it is using false every time the hook renders, despite your providing new props to the hook. Change the first line of your test to

    const hook = renderHook((isVisible) => useRenderedAt(isVisible), {
      initialProps: false
    });

allows the test to pass.

We should document this better(apparently this is not documented at all).

from react-hooks-testing-library.

DavidBabel avatar DavidBabel commented on May 20, 2024 18

Ok i find out. So for googlers, the answer is no. Ne need for async since the hooks is synchrone.

so this works perfectly :

  test('should return render time when viewable and never reupdate it', () => {
    const hook = renderHook(isVisible => useRenderedAt(isVisible), {
      initialProps: false
    });
    hook.rerender(true);
    const timestamp = hook.result.current;
    expect(timestamp).not.toBe(Infinity);
    hook.rerender(true);
    expect(hook.result.current).toBe(timestamp);
    hook.rerender(false);
    expect(hook.result.current).toBe(timestamp);
  });

from react-hooks-testing-library.

goldo avatar goldo commented on May 20, 2024 6

@DavidBabel thanks for writing this down.

I find this rerender API not intuitive and complicated for something like that :(

from react-hooks-testing-library.

DavidBabel avatar DavidBabel commented on May 20, 2024 2

We should document this better(apparently this is not documented at all).

Yeah that's why i was a bit confused about that. Thanks for your answer, it totally makes sense now. I did not have the energy to check in the code yesterday :p

Great project anyway

Edit: I actually reopened. Do i have to use waitForNextUpdate in my case ?
Or this is enough ? :

    const hook = renderHook(isVisible => useRenderedAt(isVisible), {
      initialProps: false
    });
    hook.rerender(true);
    const timestamp = hook.result.current;
    expect(timestamp).not.toBe(Infinity);
    hook.rerender(true);
    expect(hook.result.current).toBe(timestamp);

from react-hooks-testing-library.

DavidBabel avatar DavidBabel commented on May 20, 2024

Glad it helps

from react-hooks-testing-library.

mpeyper avatar mpeyper commented on May 20, 2024

@goldo, I'd be interested in hearing your thoughts in #56 about why you find this rerender API not intuitive and complicated.

@DavidBabel you're welcome to leave your thoughts too :)

from react-hooks-testing-library.

goldo avatar goldo commented on May 20, 2024

@mpeyper I think mainly because you have to recreate a function and map the params of it to the params of the function of your hook.
Ex:

  test('useMyHook', () => {
    const hook = renderHook(number=> useMyHook({timeout, ref, number}), {
      initialProps: false
    });
    hook.rerender(5);
  });

Here, hook.rerender(5) is not explicit at all and you have to learn and adapt your mapping test function.

I guess It would have been better to keep the exact same function signature for example ?

from react-hooks-testing-library.

mpeyper avatar mpeyper commented on May 20, 2024

Here, hook.rerender(5) is not explicit at all and you have to learn and adapt your mapping test function.

Generally, and what the examples in the new draft docs have, I would use an object for the props so that you can name the value to add a bit of traceability to the value and it's usage

  test('useMyHook', () => {
    const hook = renderHook(({ number }) => useMyHook({timeout, ref, number}), {
      initialProps: { number: false }
    });
    hook.rerender({ number: 5 });
  });

But I totally understand that this still is not as explicit as you might want. It's probably a case of it being apparent to me, the author of the library, but not so much for fresh eyes seeing the API for the first time.

I guess It would have been better to keep the exact same function signature for example ?

You mean like

  test('useMyHook', () => {
    const { rerender } = renderHook(() => useMyHook({timeout, ref, false}));
    rerender(() => useMyHook({timeout, ref, 5}));
  });

or

  test('useMyHook', () => {
    renderHook(() => useMyHook({timeout, ref, false}));
    renderHook(() => useMyHook({timeout, ref, 5}));
  });

Or something else?

from react-hooks-testing-library.

goldo avatar goldo commented on May 20, 2024
test('useMyHook', () => {
    const hook = renderHook(()=> useMyHook({timeout, ref, number}));
    hook.rerender({ number });
  });

something like this ?

from react-hooks-testing-library.

mpeyper avatar mpeyper commented on May 20, 2024

I would like to move this discussion to #56, but I'll answer here for continuity.

something like this ?

I'm not sure where number gets defined or updated to understand the usage of that one.

if its:

test('useMyHook', () => {
  const timeout = 100 // or whatever
  const ref = { current: '' } // or whatever
  let number = false

  const hook = renderHook(()=> useMyHook({ timeout, ref, number }));

  number = 5
  hook.rerender({ number });
});

Then passing the updated value to rerender is unnecessary as the hook callback will already pick up the new value when rerendering, so it could just be:

test('useMyHook', () => {
  const timeout = 100 // or whatever
  const ref = { current: '' } // or whatever
  let number = false

  const hook = renderHook(()=> useMyHook({ timeout, ref, number }));

  number = 5
  hook.rerender();
});

This would work with the current API.

If the intention was something more like:

test('useMyHook', () => {
  const timeout = 100 // or whatever
  const ref = { current: '' } // or whatever

  const hook = renderHook(()=> useMyHook({ timeout, ref, number: false }));

  hook.rerender({ number: 5 });
});

Then I don't think this is possible as the hook callback has no idea about the value passed to rerender, which is why the current implementation has initialProps that get passed into the hook callback, so it can update them with the incoming values from rerender.

I still think I may be completely misunderstanding what you are saying though.

from react-hooks-testing-library.

goldo avatar goldo commented on May 20, 2024

@mpeyper sorry for the delay
Yes I though more about your last example, it seems to be the more obvious and readable to me. I didn't think about it more deeply in its implementation, I didn't check the code neither, so my bad, but I guess there should be a better way anyway

from react-hooks-testing-library.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.