salivan salivan - 1 month ago 5
React JSX Question

passing default object as function parameter es6 works but not as plain parameter

I don't get it, why this works?

import React from 'react'

import './Card.scss'

export default ({ type = 'single' }) => (
<div>{type}</div>
)


and this doesn't?

import React from 'react'

import './Card.scss'

export default ( type = 'single' ) => (
<div>{type}</div>
)

Answer

In a comment, you've said you're using it as a React component directly, e.g.:

<Card type="single" />

and

<Card/>

You need to use the destructured version (your first example) because React components are called with a single argument, an object containing the properties for the component (a blank object if you don't specify any properties). A non-destructured one doesn't make sense, the type you'd receive would be an object, not a string.

Here's a snippet demonstrating what React passes to the component, which should clarify why expecting a simple argument as a string won't work:

let Example = (props) => (
  <div>props: [{JSON.stringify(props)}]</div>
);
let Card = ({type = "simple"}) => (
  <div>Type: [{type}]</div>
);
ReactDOM.render(
  <div>
    <Example />
    <Example answer="42" />
    <Card type="simple" />
  </div>
  ,
  document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>


Original answer before you clarified you were using this directly as a component:

Both work, it's a matter of how you call each of them.1

Your first example should be called like this:

import thingy from 'somewhere';
thingy({type: 'double'});
//     ^--------------^---- note it's an object

...because it destructures its argument.

Your second example should be called like this:

import thingy from 'somewhere';
thingy('double');
//     ^------^---- note it's not an object

...because it just uses a simple argument.

Separately: Your first example doesn't have a default value for the argument, so you can't call it with no arguments at all:

// Doesn't work for the first example
thingy();

If you wanted to be able to do that, you'd need to supply an overall default:

export default ({ type = 'single' } = {}) => (
// Overall default ----------------^^^^^
  <div>{type}</div>
)

But your second example can be called with no arguments at all, because it has a default for its only argument.

(That doesn't matter, React always calls it with a single object argument.)

Comments