-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
ReactWrapper.update() is not forcing a re-render #2042
Comments
Since this relies on an impure render (which is obviously a very bad idea in React), can you elaborate on the actual use case where this is popping up? If props and state and context haven't changed, a rerender shouldn't need to call |
Yea the min-repro isn't a real use-case (but it is pulled from Enzyme documentation). I'm trying to write a test to validate that a context provider is providing the same context object between render cycles, and only providing a new object when a certain prop or parent context is changed. This involves checking object references after multiple renders of a component. The above component could easily be changed to have a "pure" render by removing |
Hmm, that does make sense. It does stand to reason that a call to |
Hi, I've also just run into the same issue. I definitely understand that impure renders are a bad idea, but in my case I'm testing something that involves mocking out a render prop component that relies on external state. The real version of the component updates its own state and re-renders, but in the mock it's easier to just craft calls to the Since you tagged as |
@uhoh-itsmaciek yes, but be aware many other methods call into |
Interesting. Why would they be calling it? The internal documentation is the same: the method forces a re-render. |
They call it when state and/or props change, usually. I'm just saying we'll have to be careful about it, and that it might be better to refactor so that the current behavior is preserved for all internal update attempts. |
Any updates on this? |
Nope, it's still open, has the "help wanted" label, and there's no associated PR. |
I'm having the same issue. Doing |
Having the same issue. Having gone through this thread, the easiest solution is to update the docs, stating that it updates only if there were some changes to props/state. If |
Event
|
What does |
|
|
In your test assertion is never triggered because test runner never has a chance to wait until |
Im not 100% sure but i think that: Enzyme's update() method checks if props/state changed and based on that decides to update component or not. forceUpdate() in this case is actually React's method. Notice that you don't call it at wrapper but at wrapper.instance(). It causes a re-render no matter what https://reactjs.org/docs/react-component.html#forceupdate. I'd say that this is acceptable solution. |
|
@shaun-weddell - You're absolutely right. For React FC - the |
This code works for functional component:
Actually, my component even don't need to have a prop foo. |
Following @PFight idea, this generic approach worked for me: const component = mount(<YourComponent {...anyProps} />);
component.setProps(); // Forces react component tree to re-render.
component.update(); // Syncs the enzyme component tree snapshot with the react component tree. |
Actually, since |
@mmassaki you're right! just fixed the suggestion! thanks! |
|
In other words, if you haven't changed any props or state, there's nothing to rerender. |
in my particular case, its not the "rendering" i care about but its the only way I can get the new mock value to be recognized... Note: in a in this test I want to mock a different return value. if i dont force the rerender with
|
What do you mean the new mock value? All mocks should be done before creating the wrapper. It makes no sense whatsoever to call |
hmmm interesting.... Ive written a few thousand tests set up like that. 🤣 my bad. i usually do a shallow in the before each and then set props and state in each test and assert im getting the desired results. gets rid of a lot of boiler plate and ensures I always get a fresh render. why does it "makes no sense whatsoever"? It seems like it is repetition, just automatic? i.e. what is the problem in doing it in a |
The difference is that each test that has a tiny modification can change it without shenanigans like "oops, let me update the wrapper and rerender it", and that failure messages are clearer. |
yes, i guess my code snippet above proves your point. If i was mocking before i created the wrapper in each test I wouldnt have the problem I do. Thanks! The crazy part is the |
How to force to re-render the component, when I'm updating redux state with store.dispatch(action)? |
I know this is an old issue, but in case anyone ever comes across this issue while trying to test redux Assuming your component has something like this: const someState = useSelector(getSomeState); In your test file: describe('checks some state', () => {
let stateSpy;
beforeAll(() => {
nextActiveStageSpy = jest.spyOn(selectors, "getSomeState").mockImplementation(() => "new-state");
});
afterAll(() => {
nextActiveStageSpy.mockRestore();
});
...
} |
Current behavior
min-repro here: https://github.com/nicholasrice/enzyme-react-wrapper-update-repro
Using
mount
to mount a component, calling theupdate
method of the returnedReactWrapper
instance does not seem to be forcing a re-render. With slight changes, I implemented the example from https://airbnb.io/enzyme/docs/api/ReactWrapper/update.html and am expierencing a test failure.On a slight aside, I think the assertions being made in the above documentation should be
1
for the first call and2
for the second call, instead of0
for the first call and1
for the second.Expected behavior
I would expect that calling the
update
method of aReactWrapper
would call the render method of the mounted component.Your environment
API
Version
Adapter
The text was updated successfully, but these errors were encountered: