skip to Main Content

I’m trying to wrap my head around why this happens I have the following code in App to render a child component with some props that I make and pass in:

function App() {
  const items = [
    {
      label: 'Hello',
      content: 'Testing Content'
    },
    {
      label: 'Something else',
      content: 'More Content'
    },
    {
      label: 'Final',
      content: 'Last Content'
    }
  ]

  return (
    <div className="App">
      <Accordion displayData={items} />
    </div>
  );
}

export default App;

In my accordion component I take the props and call map to return some jsx to the return statement which should yield my list in theory:

function Accordion({
    displayData,
    ...otherProps
}) {

    function displayAccordionItems () {
        displayData.map((itm, idx) => {
            return (
                <div key={idx}>
                    <p>{itm.label}</p>
                    <p>{itm.content}</p>
                </div>
            )
        })
    }
    return <div>Hello from accordion {displayAccordionItems}</div>;
}

export default Accordion;

Nothing from the props renders and I’m given the error in the console. I’ve tried calling it by referrence {displayAccordionItems} & executing it with {displayAccordionItems()} both approaches yield the same error.

I’ve look at previous solutions to this type of question but alot of them are using class components which I’m not here and require executing the method with () as opposed to trying it by reference which I’ve tried already.

Any explanation or docs reference would be super handy!

2

Answers


  1. The displayAccordionItems does not return anything.
    Add a return statement.

    Also, displayAccordionItems alone is just a function. It would help if you executed it to get the result.

    change your code this way,

     function Accordion({ displayData, ...otherProps }) {
        function displayAccordionItems() {
            // Return the result of map
            return displayData.map((itm, idx) => {
                return (
                    <div key={idx}>
                        <p>{itm.label}</p>
                        <p>{itm.content}</p>
                    </div>
                );
            });
        }
        // Call displayAccordionItems to render its return value
        return <div>Hello from accordion {displayAccordionItems()}</div>;
    }
    
    export default Accordion;
    
    Login or Signup to reply.
  2. While Isuru’s answer is correct, it’s an anti-pattern* to declare a render function inside the body of a component due to it causing confusion/readability issues.

    It can be much more simpler written:

     function Accordion({ displayData, ...otherProps }) {
        return (
           <div>
             Hello from accordion {displayData.map((itm, idx) => {
                return (
                    <div key={idx}>
                        <p>{itm.label}</p>
                        <p>{itm.content}</p>
                    </div>
                );
            })}
           </div>
         )
    
    }
    
    export default Accordion;
    
    

    It seems minor in such a small component. But components grow, and these renderXXX functions defined inside the component body get hard to grok surprisingly quickly simply because you can’t just read what’s being rendered – you’re forced to reder what’s being rendered, then jump to the renderXXX to see what it returns (and potentially so on if you do it again, which definitely happens).

    KISS

    *I’m not normally a fan of dev.to articles – they tend to be flame-war-y, but this one is very correct. renderThing methods are a hold-over from class components (and I personally think large and numerous renderThing methods were actually some of the reasons that Reacts API started pushing people towards functional components)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search