enzyme
enzyme copied to clipboard
useEffect not working with mount
Current behavior
I have 2 files below
index.js
:
import React, { useEffect, useState } from "react";
export const MyComponent = (props) => {
const [val, setVal] = useState(0);
useEffect(() => {
setVal(props.value);
}, [props.value]);
return <div value={val} />;
};
index.test.js
:
import React from "react";
import { MyComponent } from ".";
import { mount, configure } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
configure({ adapter: new Adapter() });
it("should work", () => {
const component = mount(<MyComponent value={10} />);
component.setProps({ value: 4 });
expect(component.find("div").prop("value")).toEqual(4);
});
See more here: https://codesandbox.io/s/7zjfo?file=/index.test.js
Expected behavior
The test goes success, the prop value
that child div
should received should be updated to 4
instead of remaining 10
.
Current behavior
It remains 10.
As my exploiting, the useEffect
is working and the val
state is updated to 4
. So the div should be received 4
. But when getting value from the .find().prop()
it does not updated but remains old value 10
. So I think this could be bug from enzyme adapter as it revert any changes from useState
(?, I'm not sure).
Your environment
API
- [ ] shallow
- [x] mount
- [ ] render
Version
library | version |
---|---|
enzyme | ^3.11.0 |
react | 16.13.1 |
react-dom | ^16.0.0 |
react-test-renderer | |
adapter (below) | ^1.15.6 |
Adapter
- [x] enzyme-adapter-react-16
- [ ] enzyme-adapter-react-16.3
- [ ] enzyme-adapter-react-16.2
- [ ] enzyme-adapter-react-16.1
- [ ] enzyme-adapter-react-15
- [ ] enzyme-adapter-react-15.4
- [ ] enzyme-adapter-react-14
- [ ] enzyme-adapter-react-13
- [ ] enzyme-adapter-react-helper
- [ ] others ( )
I found that if I add an additional call component.update()
before querying the value, Enzyme's snapshot tree have been updated and it returns value corrected.
Update: Even when I using component.update()
's callback, it still does not work. But noticable thing here that the component was actual received the value, rendered the new value but somehow the component
wrapper does not update the snapshot.
My code:
index.js
:
import React, { useEffect, useState } from "react";
export const MyComponent = (props) => {
const [val, setVal] = useState(0);
useEffect(() => {
setVal(props.value);
console.log("MyComponent have received new value:", props.value);
}, [props.value]);
console.log("MyComponent is rendering with val =", val);
return <div value={val} />;
};
index.test.js
:
import React from "react";
import { MyComponent } from ".";
import { mount, configure } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
configure({ adapter: new Adapter() });
it("should work", () => {
const component = mount(<MyComponent value={10} />);
component.setProps({ value: 4 });
expect(component.find("div").prop("value")).toEqual(4);
});
it("callback should work too", () => {
const component = mount(<MyComponent value={10} />);
component.setProps({ value: 4 }, () => {
expect(component.find("div").prop("value")).toEqual(4);
});
});
it("why does it need .update() to be called?", () => {
const component = mount(<MyComponent value={10} />);
component.setProps({ value: 4 });
component.update();
expect(component.find("div").prop("value")).toEqual(4);
});
it("even with .update(), callback does not worked", () => {
const component = mount(<MyComponent value={10} />);
component.setProps({ value: 4 }, () => {
component.update();
expect(component.find("div").prop("value")).toEqual(4);
});
});
Sandbox: https://codesandbox.io/s/7zjfo?file=/index.test.js