Reputation: 32721
I just want to know why the following original codes can be shortened using {...rest}
in arguments and spread in attributes as you can see in the simplified code.
In the simplified code it uses {...rest}
spread to make value={value} onChange={onChange} type={type}
. I am not sure how it is possible.
Original code
import React from "react";
const Input = ({ type, name, label, error, value, onChange }) => {
return (
<div className="form-group">
<label htmlFor={name}>{label}</label>
<input
value={value}
onChange={onChange}
type={type}
name={name}
id={name}
className="form-control" />
{error && <div className="alert alert-danger">{error}</div>}
</div>
);
};
export default Input;
Simplified code
import React from "react";
const Input = ({ name, label, error, ...rest }) => {
return (
<div className="form-group">
<label htmlFor={name}>{label}</label>
<input {...rest} name={name} id={name} className="form-control" />
{error && <div className="alert alert-danger">{error}</div>}
</div>
);
};
export default Input;
Upvotes: 2
Views: 164
Reputation: 1886
In the first snippet, you are accepting type
, name
, label
, error
, value
and onChange
then using their values directly as you stated.
In the second snippet, you use the rest operator (from MDN):
A function's last parameter can be prefixed with ... which will cause all remaining (user supplied) arguments to be placed within a "standard" javascript array. Only the last parameter can be a "rest parameter".
The rest parameter works the same in vanilla JavaScript:
const data = {
"item1": "apples",
"item2": "bananas",
"item3": "grapes",
"item4": "limes"
};
function f({item1, item2, ...data}) {
console.log("item1:", item1);
console.log("item2:", item2);
console.log("item3:", data.item3);
console.log("item4:", data.item4);
}
f(data);
As does the spread operator (from MDN):
Spread syntax allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected.
const data = {
"item1": "apples",
"item2": "bananas",
"item3": "grapes",
"item4": "limes"
};
const f = (items) => {
for (let x in items) {
console.log(x + ":", items[x]);
}
}
f({...data})
The fact that you are using them with React components makes no difference.
Upvotes: 0
Reputation: 112927
...rest
is used to put all the properties that are not destructured in a separate object.
const obj = {
name: 'name',
label: 'label',
error: 'error',
foo: 'foo',
bar: 'bar'
};
const { name, label, error, ...rest } = obj;
console.log(rest);
This rest
object is then used for the spread syntax
to pass each property in the object as a separate prop. It might be easier to see why this works if you write the JSX as compiled React.createElement
calls.
React.createElement("input", {
name: name,
id: name,
className: "form-control",
...rest
});
const obj = {
name: 'name',
label: 'label',
error: 'error',
foo: 'foo',
bar: 'bar'
};
const { name, label, error, ...rest } = obj;
const result = {
name: name,
id: name,
className: "form-control",
...rest
};
console.log(result);
Upvotes: 4