inferno: inferno-clone-vnode doesn't include children in cloned node
Inferno Metadata OS: OS X Browser: Chrome Package: inferno-clone-vnode version tested: 5.6.1 & 6.0.0-rc.5
Observed Behaviour I am upgrading from inferno 3.x to 5.6.1 and as I was testing my codebase I came across an instance where a cloned node wasn’t including its children. This behavior is different than what I was seeing in 3.x so I checked the docs to see if cloneVNode had changed:
Clone and return a new Inferno VNode using a VNode as the starting point. The resulting VNode will ?>have the original VNode’s props with the new props merged in shallowly. New children will replace >existing children. key and ref from the original VNode will be preserved.
Expected Current Behaviour
Given that cloneVNode did not require the children to be passed as a third argument in previous version of Inferno, I feel like the children argument is optional and is intended to overwrite existing children, not empty the children completely, even if no children are passed in. Therefore, this ticket seeks to do the following:
- Should cloneVNode behave the way it did in 3.x or is it expected that I should specify the children when calling it every time? My personal feeling is that I shouldn’t have to specify the children as it seems redundant.
- Show a test in which the children are not included in the cloned node:
import { render, Component } from "inferno";
import { cloneVNode } from "inferno-clone-vnode";
describe("cloneVNode", () => {
let el;
beforeEach(() => {
class NameContainer extends Component {
render() {
const children = this.props.children.map(c =>
cloneVNode(c, {
name: "Henry"
})
);
return <span>{children}</span>;
}
}
const NameViewer = () => {
return (
<NameContainer>
<div>
<span>A child that should render after the clone</span>
</div>
<div>
<span>A child that should render after the clone</span>
</div>
</NameContainer>
);
};
el = document.createElement("div");
document.body.appendChild(el);
render(<NameViewer />, el);
});
it("should render", () => {
expect(el).toMatchSnapshot();
});
});
And here is the resulting snapshot:
exports[`cloneVNode should render 1`] = `
<div>
<span>
<div
name="Henry"
/>
<div
name="Henry"
/>
</span>
</div>
`;
Notice that the span children are not included. Now, if I update the NameContainer class as follows:
class NameContainer extends Component {
render() {
const children = this.props.children.map(c =>
cloneVNode(c, {
name: "Henry"
}, c.children)
);
return <span>{children}</span>;
}
}
Let’s look at the resulting snapshot:
exports[`cloneVNode should render 1`] = `
<div>
<span>
<div
name="Henry"
>
<span>
A child that should render after the clone
</span>
</div>
<div
name="Henry"
>
<span>
A child that should render after the clone
</span>
</div>
</span>
</div>
`;
Now the children are included. I tried putting together a fiddle but inferno-clone-vnode is not hosted on the cdn. The next best thing I could do is put together a jest test. Again, my personal opinion is that it is redundant to have to specify the children and this was not required in Inferno@3.x. What are your thoughts? If you would like me to address the issue i’m willing to create a PR. Thanks for your time.
Regards,
Will
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 15 (15 by maintainers)
Commits related to this issue
- inferno-clone-vnode doesn't include children in cloned node Fixes #1393. inferno-clone-vnode does not currently clone existing children of a vnode. Instead, we are required to specify the children t... — committed to johnsonw/inferno by johnsonw 6 years ago
- inferno-clone-vnode doesn't include children in cloned node (#1394) Fixes #1393. inferno-clone-vnode does not currently clone existing children of a vnode. Instead, we are required to specify the... — committed to infernojs/inferno by johnsonw 6 years ago
- Simplifies cloneVNode and fixed issue Github #1393 — committed to infernojs/inferno by Havunen 6 years ago
@Havunen, no problem. I’ll start working on this tonight 👍
Hi @Havunen,
I’ve updated the source locally and the majority of my tests are passing now. I still have a few I am working through (not sure that they are related to this). Once all of the tests are passing i’m going to go through and do a manual test and then I should be able to commit the change. I might have it later tonight. Will keep you posted.