为什么可以在属性中使用{... rest}

时间:2018-11-04 01:10:35

标签: javascript reactjs ecmascript-6

我只想知道为什么可以在参数中使用{...rest}来缩短以下原始代码,并在简化的代码中看到这些属性在属性中的分布。

在简化代码中,它使用{...rest}扩展来生成value={value} onChange={onChange} type={type}。我不确定这怎么可能。

原始代码

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;

简化代码

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;

2 个答案:

答案 0 :(得分:4)

...rest用于将所有未分解的属性放在单独的对象中。

const obj = {
  name: 'name',
  label: 'label',
  error: 'error',
  foo: 'foo',
  bar: 'bar'
};
const { name, label, error, ...rest } = obj;

console.log(rest);

然后将此rest对象用于spread syntax,以将对象中的每个属性作为单独的prop传递。如果您将JSX编写为已编译的React.createElement调用,可能会更容易理解为什么这样做。

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);

答案 1 :(得分:0)

在第一个代码段中,您接受typenamelabelerrorvalueonChange,然后使用它们的值直接按照您所说的进行。

在第二个片段中,您使用rest运算符(来自MDN):

  

函数的最后一个参数可以加...前缀,这将导致所有剩余的(用户提供的)参数都放在“标准” javascript数组中。只有最后一个参数可以是“休息参数”。

rest参数在原始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);

传播操作符(来自MDN)也一样:

  

扩展语法允许将可迭代的对象(例如数组表达式或字符串)扩展到期望零个或多个参数(用于函数调用)或元素(用于数组文字)的位置,或将对象表达式扩展在需要扩展零位的位置预期零(或更多)键值对(用于对象文字)。

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})

将它们与React组件一起使用的事实没什么区别。