First a look in JSX. When you do (scenario 1):
<Component myProp={something} />
The something typically is a JavaScript expression.
When you use the spread operator, like (scenario 2):
<Component {...something} />
Then something should be a JavaScript object.
Your case
Considering objA and objB are two JavaScript objects, you can use them like scenario 2 above:
<Component {...objA} {...objB} />
And they should work as expected.
When you do:
let bothObjects = {...objA, ...arrB};
<Component {...bothObjects} />
Again, it works because bothObjects is too an object. Just one object that happens to have been built based on objA and objB.
The other case:
<Component {...{...objA,...objB}} />
May seem weird, but works perfectly. See, from scenario 2 above, JSX expects (in {...something}) that something is an object. And {...objA,...objB} is an object. Well, it's actually an expression that "returns" a value of object type, but it's the same. It works fine.
The last case:
<Component {...objA, ...objB} />
Does not work because the expresion objA, ...objB is not a JavaScript object. It actually means nothing, it is a syntax error. See the error message:
VM2296 babel.js:17994 Uncaught SyntaxError: Babel script: Unexpected token, expected }
30 |
31 | <Bob
> 32 | {...objA, ...objB}
| ^
As you can see, after the char A of ...objA, JSX just expected to find the }. But it found a , which is an error (Unexpected token).
What to use?
Considering all three forms that work:
let bothObjects = {...objA, ...arrB};
<Component {...bothObjects} />
<Component {...objA} {...objB} />
<Component {...{...objA,...objB}} />
To say which one is better is just a matter of taste. Pick whatever you think is more readable.
Answer from acdcjunior on Stack OverflowFirst a look in JSX. When you do (scenario 1):
<Component myProp={something} />
The something typically is a JavaScript expression.
When you use the spread operator, like (scenario 2):
<Component {...something} />
Then something should be a JavaScript object.
Your case
Considering objA and objB are two JavaScript objects, you can use them like scenario 2 above:
<Component {...objA} {...objB} />
And they should work as expected.
When you do:
let bothObjects = {...objA, ...arrB};
<Component {...bothObjects} />
Again, it works because bothObjects is too an object. Just one object that happens to have been built based on objA and objB.
The other case:
<Component {...{...objA,...objB}} />
May seem weird, but works perfectly. See, from scenario 2 above, JSX expects (in {...something}) that something is an object. And {...objA,...objB} is an object. Well, it's actually an expression that "returns" a value of object type, but it's the same. It works fine.
The last case:
<Component {...objA, ...objB} />
Does not work because the expresion objA, ...objB is not a JavaScript object. It actually means nothing, it is a syntax error. See the error message:
VM2296 babel.js:17994 Uncaught SyntaxError: Babel script: Unexpected token, expected }
30 |
31 | <Bob
> 32 | {...objA, ...objB}
| ^
As you can see, after the char A of ...objA, JSX just expected to find the }. But it found a , which is an error (Unexpected token).
What to use?
Considering all three forms that work:
let bothObjects = {...objA, ...arrB};
<Component {...bothObjects} />
<Component {...objA} {...objB} />
<Component {...{...objA,...objB}} />
To say which one is better is just a matter of taste. Pick whatever you think is more readable.
Rest parameters should be the last named argument of a function, you're passing two. You should divide both into separate props, like in your working example:
<Component {...objA} {...objB} />
In this example you have two props, the with Rest parameter is the first one.
function sum(...theArgs, q) {
return theArgs.reduce((previous, current) => {
return previous + current;
});
}`
When I put the q parameter it gives me the error:
Error: parameter after rest parameter
EDIT: And @Omar is right, in this case there's no need for using Rest Parameters, since both are simple objects
Spread operator with React component props
What is the point of using the spread operator to pass props while also passing props individually?
reactjs - Spread operator in react component props - Stack Overflow
HOC /Props and Spread Operators
I'm building a react component library and am confused as to why the example passes props via the spread operator but also passes those same props individually. Below is the code I am working with. Specifically I am looking at the Button component props and the StyledButton props. Any clarification would be great, thanks!
import React,{FC} from 'react'
import styled from 'styled-components';
import { MouseEventHandler } from "react"
export interface ButtonProps {
text?: string,
primary?:boolean,
disabled?: boolean,
size?: "small" | "medium" | "large",
onClick?: MouseEventHandler<HTMLButtonElement>
}
const StyledButton = styled.button<ButtonProps>`
border: 0;
line-height: 1;
font-size: 15px;
cursor: pointer;
font-weight: 700;
font-weight: bold;
border-radius: 3px;
display: inline-block;
padding: ${props => props.size === "small"? "7px 25px 8px" : (props.size === "medium"? "9px 30px 11px" : "14px 30px 16px" )};
color: ${props => props.primary? "#1b116e":"#ffffff"};
background-color: ${props => props.primary ? "#6bedb5":"#1b116e"};
opacity: ${props => props.disabled ? 0.5 : 1};
&:hover {
background-color: ${props => props.primary ? "#55bd90":"#6bedb5"};
}
&:active {
border: solid 2px #1b116e;
padding: ${props => props.size === "small"? "5px 23px 6px" : (props.size === "medium"? "7px 28px 9px" : "12px 28px 14px" )};
}
`;
const Button: FC<ButtonProps> = ({size, primary, disabled, text, onClick, ...props}) => {
return (
<StyledButton type="button" onClick={onClick} primary={primary} disabled={disabled} size={size} {...props}>
{text}
</StyledButton>
)
}
export default Button;The ... spreads the next spreadable item. In your case if you evaluate the isActive to true you will find,
...{bg: "teal.200", rounded: "sm",}
So the spread operator spread this {bg: "teal.200", rounded: "sm",} object and returns bg: "teal.200", rounded: "sm" so that they can be passed as props.
To explain the spread operator in simple words, it spreads all the properties inside your component.
lets say, you pass a property title = "Side Link", this gets automatically assigned into the Side Nave link component so you don't need to specifically add this prop to retrieve the value.
If you had multiple props passed from parent, and you don't want to manually add them all in the Side Nav Link component, you can use the spread operator and it will spread all those props to the component.
<NavLink href={href}>
{(isActive) => (
<SideNavLink
{...(isActive && { // this spread operator
bg: "teal.200",
rounded: "sm",
})}
{...props} //====> title = "Side Link"
/>
)}
</NavLink>