Flimzy_Programmer
Flimzy_Programmer

Reputation: 543

Render passed components render function

I am trying to understand how to call a passed components render function inside another function. Say i have two functions i'd like to call (A and B):

export const A = (value: any) => {
return (
    <div>{value}</div>
);}

export const B = (value: any) => {
return (
    <table>
        <thead>
            <tr>
                <th>Source</th>
                <th>Description</th>
            </tr>
        </thead>
        <tbody>
            {value.map((item: any) => {
                <span>
                    <td>{Object.keys(item)}</td>
                    <td>{Object.values(item)}</td>
                </span>
            })}
        </tbody>
    </table>
);}

I would like to pass these two components into another, and have the passed component render inside the receiving component. So if i pass them like this into the CollapsibleSection component:

export class MeasureSection extends React.Component<any, any> {
  constructor(props: any) {
    super(props);
  }

  public render() {
    const { data } = this.props;
    return (
      <div>
        {data && data.map(({ ValueA, ValueB }: any, index: number) =>
          <div key={index}>

          {ValueA && <CollapsibleSection
              isCollapsed={false}
              buttonText='A'
              collapsibleSection={<A value={ValueA} />}
            />}

            {ValueB && <CollapsibleSection
              isCollapsed={false}
              buttonText='B'
              collapsibleSection={<B value={ValueB} />}
            />}
          </div>
        )}
      </div>
    );
  }
}

CollapsibleSection component:

export class CollapsibleSection extends React.Component<any, {isCollapsed: boolean}> {
    constructor(props: {}) {
        super(props);

        this.state = {
            isCollapsed: this.props.isExpanded
        }
        this._toggleCollapse = this._toggleCollapse.bind(this);
    }

    public render(): JSX.Element {
        const { isCollapsed } = this.state;
        const { buttonText, collapsibleSection } = this.props;
        return (
            <div>
                <DefaultButton
                    onClick={this._toggleCollapse} className="CollapsibleSection"
                >
                    {isCollapsed ? <i className="ms-Icon ms-Icon--ChevronUp" aria-hidden="true" /> : <i className="ms-Icon ms-Icon--ChevronDown " aria-hidden="true" />}
                    &nbsp; {buttonText}
                </DefaultButton>
                {isCollapsed && collapsibleSection.props.value}
            </div>
        );
    }

    private _toggleCollapse() {
        this.setState({ isCollapsed: !this.state.isCollapsed })
    }
}

In the collapsibleSections render function, i would like to call the passed components render function. The line

{isCollapsed && collapsibleSection.props.value}

allows me to render component A, but i'm not calling the render, i'm just extracting the value (?). That approach does not work for more complicated components like B. So how to call component A and Bs render function inside the CollapsibleSections render function? Is this approach the right way to pass components into another components or is there a smarter way?

Upvotes: 0

Views: 60

Answers (1)

mcssym
mcssym

Reputation: 944

You don’t have to call collapsibleSection.props.value just collapsibleSection like {isCollapsed && collapsibleSection} because the property collapsibleSection will contain your component.

Upvotes: 1

Related Questions