2
votes

I am studying the code for react-accessible-accordion, and I don't understand how it renders its children.

From Accordion.tsx:

export default class Accordion extends React.Component<AccordionProps> {
    // ... defaults


    renderAccordion = (accordionContext: AccordionContext): JSX.Element => {
        const {
            preExpanded,
            allowMultipleExpanded,
            allowZeroExpanded,
            onChange,
            ...rest
        } = this.props;

        return <div data-accordion-component="Accordion" {...rest} />;
    };

    render(): JSX.Element {
        return (
            <Provider
                preExpanded={this.props.preExpanded}
                allowMultipleExpanded={this.props.allowMultipleExpanded}
                allowZeroExpanded={this.props.allowZeroExpanded}
                onChange={this.props.onChange}
            >
                <Consumer>{this.renderAccordion}</Consumer>
            </Provider>
        );
    }
}

This component accepts a few levels of nested children. Specifically, I don't understand how they are being passed down.

I can see that the component spreads the rest of props over a self-closing Accordion div element... How does that mechanism manage to render multiple levels of children?

3

3 Answers

1
votes

A React context Consumer expects a function as its child to render the content. That function in this example is referenced as this.renderAccordion:

<Consumer>{this.renderAccordion}</Consumer>

Which renders the children in the {...rest} spread attributes:

        const {
            preExpanded,
            allowMultipleExpanded,
            allowZeroExpanded,
            onChange,
            ...rest
        } = this.props;

        return <div data-accordion-component="Accordion" {...rest} />;

The ...rest includes children from this.props (and you can actually render children as an attribute, like <div children={ <p>Hello!</p> } />) from the destructuring assignment -- in other words const { ...rest } = this.props includes this.props.children.

0
votes

There is Provider for providing and Consumer for rendering the child components because the props are spread to the Consumer and children is a prop of Accordian.

Here is the consumer being used

For individual components such as the AccordianItem, this uses Provider to define components which are meant to be rendered.

0
votes

This may help you to understand.

Basically, when JSX is compiled to React code, it creates a component using:

  • React.createElement("div", null, children);, or
  • React.createElement("div", { children }, null);

Check how Hello, Foo and Bar component are compiled in the link that I sent you. Your case is gonna be the Bar component