Workshop context
Before this workshop
- Last workshop, we defined props and types for the
ButtonandCardcomponents.
This workshop
- In this workshop, we’re going to delegate props that aren’t explicitly destructured.
After this workshop
- In future workshops, we’ll handle styling of the
ButtonandCardcomponents, and animations for theSpinnercomponent.
Workshop goal
By the end of this workshop:
- Consumers of the
Buttoncomponent will be able to pass arbitrarybuttonprops to the component and the props will be used in the returnedbuttonelement.- For example,
<Button type="submit" onClick={handleClick}>Submit</Button>will return abuttonelement that hastype="submit"andonClick={handleClick}.
- For example,
- Similarly, consumers of the
Cardcomponent will be able to pass arbitraryarticleprops to the component and the props will be used in the returnedarticleelement. - Both the
classNamedefined within the component and any incomingclassNamevalues will be included in the rendered component.- For example, the output of
<Button className="button-class">Press me!</Button>will include bothbutton-classand the{styles.wrapper}class defined within the component. - Note: clsx has been installed and is available for use in this app.
- For example, the output of
Hints
Hint 1
To collect all the props that aren’t explicitly destructured, use this syntax (as described by MDN ):const { textColor, backgroundColor, children, ...delegated } = props;...delegated is not a special name; you can use whatever variable name you wish instead (for example, ...theRestOfTheProps). However, ...delegated is conventional because these props are being “delegated” from the component to its top level element.
Hint 2
To spread the props in the returned element, use this syntax:Card.tsx
function Card({
textColor,
backgroundColor,
children,
...delegated
}: CardProps) {
return (
<article
className={styles.wrapper}
{...delegated}>
{children}
</article>
);
} Hint 3
To combine the incomingclassName value with the existing value within the component, first the className prop will need to be destructured. Then, combine the value with the existing className value using clsx:Card.tsx
function Card({
textColor,
backgroundColor,
className,
children,
...delegated
}: CardProps) {
return (
<article
className={clsx(styles.wrapper, className)}
{...delegated}>
{children}
</article>
);
} Resources
- MDN docs for assigning un-destructured properties to an object
- React docs for spreading props