DNN
DNN

Reputation: 871

React - wrapped component does not render

Could someone tell me the difference between the two examples below, the top one renders correctly but the bottom one doesn't render the "XYZ" content at all? Can you also tell me why they behave differently and how I can "wrap" a component like this?

import React from 'react';
import "antd/dist/antd.css";
import {  Collapse  } from "antd";


const { Panel } = Collapse;


export default function ScraperList({ scraper }) {
    console.log(scraper);
  return (
  <Collapse accordion>
    <Panel header={scraper.name} key={scraper.id}>
      <p>XYZ</p>
    </Panel>

  </Collapse>
  );
}


import React from 'react';
import "antd/dist/antd.css";
import {  Collapse  } from "antd";


const { Panel } = Collapse;


function Scraper({ scraper: { id, name } }) {
  return (
    <Panel header={name} key={id}>
      <p>XYZ</p>
    </Panel>
  );
}

export default function ScraperList({ scraper }) {
    console.log(scraper);
  return (
  <Collapse accordion>
    <Scraper scraper={scraper}/>

  </Collapse>
  );
}


I would have thought they would work the same because the markup would be the same?

Upvotes: 1

Views: 809

Answers (1)

Agney
Agney

Reputation: 19204

This is because Collapse is using the React Children API to manipulate it's direct children and give it extra props. In this case, Collapse expects that child to be Panel and hence gives it extra props that it needs to complete the operation. This is done with cloneChild API.

React.cloneElement(
  element,
  [props],  // this is the extra props that can be passed into component.
  [...children] // this is for sending modified/new children
)

When you add an extra component like Scraper into the mix, Panel does not receive the said props and cannot render. But you can forward the props to Panel through Scraper:

import {  Collapse  } from "antd";


const { Panel } = Collapse;


function Scraper(props) {
  return (
    <Panel {...props} header={props.scraper.name} key={props.scraper.id}>
      <p>XYZ</p>
    </Panel>
  );
}

export default function ScraperList({ scraper }) {
  return (
    <Collapse accordion>
      <Scraper scraper={scraper} />
    </Collapse>
  );
}

Stackblitz Demo

While this could most certainly work, it is not the recommended way to go about it, as we might still be missing some direct relationship that they have accounted for. To see how this works with rc-collapse that AntD uses underneath:

Source

Upvotes: 2

Related Questions