Home > other >  React/Javascript passing props spread syntax vs. specific syntax
React/Javascript passing props spread syntax vs. specific syntax

Time:10-10

I am coding a recursive component.

If I pass props like this: <RecursiveComponent itemProps={data} />, it won't work. I have to pass like this: <RecursiveComponent {...data} />. Why is that?

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
import * as React from 'react'

const data = {
  name: 'Level 1',
  children: [
    {
      name: 'Level 2',
      children: [
        {
          name: 'Level 3'
        }
      ]
    },
    {
      name: 'Level 2.2',
      children: [
        {
          name: 'Level 3.2'
        }
      ]
    }
  ]
}

const RecursiveComponent = (itemsProp) => {
  const hasData = itemsProp.children && itemsProp.children.length;

  return (
    <>
      {itemsProp.name}
      {hasData && itemsProp.children.map((child) => {
        console.log(child);
        return <RecursiveComponent {...child} key={child.name} />
      })}
    </>
  )
}

function App() {
  return (
    <div className="App">
      <RecursiveComponent {...data} />
    </div>
  );
}

export default App;

CodePudding user response:

you can use it with passing props <RecursiveComponent itemProps={data} /> also, see below , notice the {} brace on props while getting props in function component.

Different way 1:-

    const RecursiveComponent = (props) => {
           const hasData = props.itemProps.children && props.itemProps.children.length
}

you can use like above as well.

Solution 2:-

import React from "react";

const data = {
  name: "Level 1",
  children: [
    {
      name: "Level 2",
      children: [
        {
          name: "Level 3"
        }
      ]
    },
    {
      name: "Level 2.2",
      children: [
        {
          name: "Level 3.2"
        }
      ]
    }
  ]
};

const RecursiveComponent = ({itemProps}) => {
  console.log("itemsprops", itemProps);
  const hasData = itemProps.children && itemProps.children.length;

  return (
    <>
      {itemProps.name}
      {hasData && itemProps.children.map((child) => {
        console.log(child);
        return <RecursiveComponent itemProps={child} key={child.name} />
      })}
    </>
  );
};

function App() {
  return (
    <div className="App">
      <RecursiveComponent itemProps={data} />
    </div>
  );
}

export default App;

CodePudding user response:

React components take an object as first argument: the props. When you use jsx, the attributes you pass are converted to an object.

<Component name="test" id={42} ok={true} /> // props = { name: "test", id: 42, ok: true }

Then your component receive the props like this:

const Component = (props) => {
    console.log(props.name) // => "test"
    // the rest of your component...
}

// Most people will use destructuration to use directly the attribute name
const Component = ({ name, id, ok }) => {
    console.log(name) // => "test"
    // the rest of your component...
}

The spread operator allow you to fill attributes for every properties of an object

const data = { name: "test", id: 42, ok: true }
<Component {...data} />
//  is the same as :
<Component name={data.name} id={data.id} ok={data.ok} />

In your case when you pass itemsProp={data} you actually have the first argument of your component like this

const RecursiveComponent = (itemsProp) => {
    // here itemsProp = { itemsProp : { name : "Level 1", children : [...] }}
    // so you have to use it this way
    const hasData = itemsProp.itemsProp.children && itemsProp.itemsProp.children.length;
}
  • Related