Hi,
I found a bug when you deconstruct props, children are not deleted properly.
Here an example:
https://codesandbox.io/s/k13proo6ko
in my case it generates a RangeError: Maximum call stack size exceeded.
const MyDiv = ({ children, ...rest }) => {
console.log(rest);
return (
<div {...rest}>
<div {...rest}>{children}</div>
</div>
);
};
Here the rest object still contains the children field.
Maybe _objectWithoutPropertiesLoose is not interpreted correctly.
Hi, this error isn't directly caused by preact but by bable not cloning your rest object but instead passing it directy twice to preacts h function.
Preact mutates the rest object as it is directly passed as props.
Look at the transformed code:
const MyDiv = ({
children,
...rest
}) => {
console.log(rest);
return h("div", rest, h("div", rest, children));
};
You can prevent this issue by: Either adding an other property to your first div or by cloning rest before passing it to the first div.
Hi,
Thanks for providing a solution to my problem on the actual version!
but the issue comes from the deconstruction step, right before,
const MyDiv = ({
children,
...rest
})
is replaced by
var MyDiv = function MyDiv(_ref) {
var children = _ref.children,
rest = _objectWithoutProperties(_ref, ['children']);
Here _objectWithoutProperties (generated by babel) doesn't works as expected with preact, it doesn't remove the children, this is generating the infinite childrend property.
No, the property is removed properly.
console.log is lazy and prints the objects state after preacts h function modified it.
You can observe this behavior by logging rest.children which eveluates to undefined instead of rest example.
@jeremycare which version of babel is used in your setup? The implementation for _objectWithoutProperties from 7.4.0 works as expected for me
@marvinhagemeister, @Kanaye is right, it works as expected! my bad
@Kanaye is right. The issue is caused by us mutating props directly. Looks like we need to clone props in createElement/h.
@jeremycare nah, that's still an issue and unexpected behaviour. We should fix that :)
Mentioned it in chat, but here's the cause:
<div {...props} />
// transpiles to:
createElement('div', props) // passed by reference
// whereas
<div a {...props} />
// transpiles to:
createElement('div', Object.assign({ a: true }, props)) // cloned first
Most helpful comment
No, the property is removed properly.
console.logis lazy and prints the objects state after preactshfunction modified it.You can observe this behavior by logging
rest.childrenwhich eveluates toundefinedinstead ofrestexample.