Props, children and destructuring
Props are an object whose reactive entries are getters.
Props are an object whose reactive entries are getters. Read them as props.title inside JSX, effects and
closures and they stay live. Reading a prop in the component body outside of those, for example to seed state
as in useStore(props.start), reads it once, exactly as React's initial state does.
ShadowJS is forgiving about destructuring. The compiler rewrites it so the names follow props. This is exact:
| Code | Live? |
|---|---|
function Row({ label, size = 3 }) |
Yes. Defaults apply only when the prop is undefined |
const { label } = props; at the top level of the component |
Yes |
const { label, ...rest } = props; |
No: rest and nested patterns are left alone. Use splitProps |
let { label } = props; |
No: only const is rewritten |
| Destructuring inside a nested function or block | No |
| A function that is not a component | No. A component is a PascalCase function with at most one parameter that contains JSX |
import { splitProps } from "@shadow-js/core";
export function Live({ label, size = 3 }: { label: string; size?: number }) {
return (
<p>
{label}-{size}
</p>
);
}
export function FromBody(props: { label: string }) {
const { label } = props;
return <p>{label}</p>;
}
export function Rest(props: { label: string; id: string }) {
const { label, ...rest } = props;
return (
<p>
{label}-{rest.id}
</p>
);
}
export function Split(props: { label: string; id: string }) {
const [own, rest] = splitProps(props, ["label"]);
return (
<p>
{own.label}-{rest.id}
</p>
);
}
export function LetBinding(props: { label: string }) {
let { label } = props;
return <p>{label}</p>;
}
Children are props.children. Type them with ParentProps from @shadow-js/web. To walk or read them more than
once, resolve them with children(() => props.children) from @shadow-js/core; it memoizes the result and
exposes toArray(). mergeProps replaces { ...defaults, ...props } and splitProps replaces rest destructuring,
and both keep getters live.