preactjs / preact-compat

ATTENTION: The React compatibility layer for Preact has moved to the main preact repo.
http://npm.im/preact-compat
MIT License
949 stars 148 forks source link

Children incompatibility with React #436

Closed samouss closed 5 years ago

samouss commented 7 years ago

preact-compat does some tweaks around the children to be react compliant. When an array is passed as children and the array contains only one element it will be unwrap (it's a bit simplify).

But in preact every children are arrays! So preact-compat is not able to make a distinction on children passed as array of one element or a primitive types (see exemple below).

One solution would to have access to the original children passed to be able to make the difference between the two.

const Sample = ({ children }) => {
  console.log(children);
  return null;
};

<Sample>
  foobar
</Sample>

// react => 'foobar'
// preact-compat => 'foobar'

<Sample>
  {['foobar']}
</Sample>

// react => ['foobar']
// preact-compat => 'foobar'
Joker-Jelly commented 6 years ago

I have same problem. And I find some compatible code in preact-compat source. React props.children seem all change to Array, it's still necessary right now? @developit

// React annoyingly special-cases single children, and some react components are ridiculously strict about this.
var c = props.children;
if (c && Array.isArray(c) && c.length === 1 && (typeof c[0] === 'string' || typeof c[0] === 'function' || c[0] instanceof VNode)) {
  props.children = c[0];

  // but its totally still going to be an Array.
  if (props.children && typeof props.children === 'object') {
    props.children.length = 1;
    props.children[0] = props.children;
  }
}
developit commented 6 years ago

This requires a change in Preact.

marvinhagemeister commented 5 years ago

We did that change with Preact X :tada: Make sure to alias preact/compat instead of preact-compat.