ChatGPT解决这个技术问题 Extra ChatGPT

React 中的这三个点在做什么?

... 在这个 React(使用 JSX)代码中做了什么,它叫什么?

<Modal {...this.props} title='Modal heading' animation={false}>
注意:... 运算符在不同的上下文中表现不同。在这种情况下,它是@TJ Crowder 在下面描述的“传播”运算符。在不同的上下文中,这也可能是@Tomas Nikodym 下面描述的“休息”运算符。
... 正在将 this.props 数组解构为其单独的值
它从数组中复制所有以前的数据
它在这两种情况下的作用不同: 1. 当在 objectarray 的名称后面使用时,它会获取所有元素并将它们克隆到您的新对象中或大批。在您的情况下,所有道具都传递给 Modal 组件。当您想在不操作第一个对象的情况下将新对象添加到数组中时,这可能很有用,例如更新状态。 2. 在对象/数组元素列表的末尾使用时,例如 const {a,b, ...rest} = obj。现在,您从其余元素中获得了一个新的 obj/arr,除了像 a、b 这样取出的元素。

T
T.J. Crowder

那是property spread notation。它是在 ES2018 中添加的(数组/迭代的传播更早,ES2015),但它在 React 项目中通过转译得到了很长时间的支持(作为“JSX spread attributes”,即使你也可以在其他地方做,不仅仅是属性)。

{...this.props} props 中的“自己的”可枚举属性展开,作为您正在创建的 Modal 元素上的离散属性。例如,如果 this.props 包含 a: 1b: 2,则

<Modal {...this.props} title='Modal heading' animation={false}>

将与

<Modal a={this.props.a} b={this.props.b} title='Modal heading' animation={false}>

但它是动态的,因此包含 props 中的任何“自己的”属性。

由于 childrenprops 中的“自己的”属性,spread 将包含它。因此,如果出现此内容的组件具有子元素,它们将被传递到 Modal。将子元素放在开始标签和结束标签之间只是语法糖 ——很好的一种 ——用于将 children 属性放在开始标签中。例子:

类示例扩展 React.Component { render() { const { className, children } = this.props;返回(

{children}
); } } ReactDOM.render( [ 第一个孩子 , 第二个孩子 } /> ], document.getElementById("root") ); .first { 颜色:绿色; } .second { 颜色:蓝色; }

扩展表示法不仅适用于该用例,而且适用于创建具有现有对象的大部分(或全部)属性的新对象 - 当您更新状态时会出现很多情况,因为您无法修改状态直接地:

this.setState(prevState => {
    return {foo: {...prevState.foo, a: "updated"}};
});

这会将 this.state.foo 替换为具有与 foo 相同的所有属性的新对象,但 a 属性变为 "updated"

常量 obj = { foo: { a: 1, b: 2, c: 3 } }; console.log("原始", obj.foo); // 创建一个 NEW 对象并将其分配给 `obj.foo` obj.foo = {...obj.foo, a: "updated"}; console.log("更新", obj.foo); .as-console-wrapper { max-height: 100% !important; }


在开始标签和结束标签之间放置一个子元素会覆盖 children 属性还是将它们组合在一起?
@anddero - 这是一个非常有趣的问题。据我所知,它是 childrennot covered by [the documentation。实验告诉我,您通过名为 children 的属性提供的子代被您在开始和结束标记之间指定的子代所取代,但如果它是未定义的行为,我一定不要依赖它。
这是一个非常好的答案。感谢代码片段示例,它使解释非常清楚。
P
Peter Mortensen

... 称为扩展属性,顾名思义,它允许扩展表达式。

var parts = ['two', 'three'];
var numbers = ['one', ...parts, 'four', 'five']; // ["one", "two", "three", "four", "five"]

在这种情况下(我将简化它)。

// Just assume we have an object like this:
var person= {
    name: 'Alex',
    age: 35 
}

这个:

<Modal {...person} title='Modal heading' animation={false} />

等于

<Modal name={person.name} age={person.age} title='Modal heading' animation={false} />

所以简而言之,我们可以说这是一条简洁的捷径。


var person = { name:'Alex',age:35} 是 json,javascript 对象表示法。 ...person 评估为 name='Alex', age=35 其目的是假设您在 json 结构中有 1,000,000 个这些键值对,并且您想将它们全部传递给组件,您所要做的就是做... 符号,它们都通过了。您不必一一列举。
这不是 ECMA 文档,不要太认真!我首先以这种方式回答了这个问题,过了一会儿,其他人将他们的答案更改为看起来像我的,只是获得了一些投票。
将有助于添加一个将对象传播到另一个对象的示例,因为这本质上就是 JSX 传播在幕后所做的。
最佳答案,清晰明了
很好的解释非常感谢!
P
Peter Mortensen

三个点代表 ES6 中的 扩展运算符。它允许我们在 JavaScript 中做很多事情:

连接数组 var shooterGames = ['使命召唤','孤岛惊魂','生化危机']; var RacingGames = ['极品飞车','Gran Turismo','倦怠']; var games = [...shooterGames, ...racingGames]; console.log(games) // ['Call of Duty', 'Far Cry', 'Resident Evil', 'Need For Speed', 'Gran Turismo', 'Burnout'] 解构数组 var shooterGames = ['Call of 《使命》、《孤岛惊魂》、《生化危机》]; var [first, ...remaining] = shooterGames;控制台.log(第一); //使命召唤console.log(remaining); //['Far Cry', 'Resident Evil'] 结合两个对象 var myCrush = { firstname: 'Selena', middlename: 'Marie' }; var lastname = '我的姓氏'; var myWife = { ...myCrush, lastname } console.log(myWife); // {firstname: 'Selena', // 中间名: 'Marie', // lastname: '我的姓氏'}

这三个点还有另一种用途,称为“休息参数”,它可以将函数的所有参数作为一个数组获取。

函数参数作为数组函数 fun1(...params) { }


这是一个很好的答案,因为每个用例都有所有清晰的示例。感谢您花时间写出所有这些。
为了更清楚起见,在示例之前提及其余参数
不仅是最佳答案,也是最有趣的答案,'Selana Marie 你的初恋:D'
3.5.解构对象
这是一个很棒的答案,作为一名 Python 开发人员,我可以将扩展运算符转换为使用 * 或 ** 表示法的打包/解包,基本上做同样的事情。
N
Nathan Kulzer

...(JavaScript 中的三个点)称为展开语法或展开运算符。这允许扩展诸如 array 表达式或 string 之类的可迭代对象,或者在放置的任何位置扩展 object 表达式。这不是 React 特有的。它是一个 JavaScript 运算符。

这里的所有这些答案都很有帮助,但我想列出 Spread Syntax(扩展运算符)最常用的实际用例。

1.组合数组(Concatenate Arrays)

有一个 variety of ways to combine arrays,但扩展运算符允许您将它放在数组中的任何位置。如果您想组合两个数组并将元素放置在数组中的任何位置,您可以执行以下操作:

var arr1 = ['two', 'three'];
var arr2 = ['one', ...arr1, 'four', 'five'];

// arr2 = ["one", "two", "three", "four", "five"]

2. 复制数组

当我们想要一个数组的副本时,我们曾经有 Array.prototype.slice() 方法。但是,您可以对扩展运算符执行相同的操作。

var arr = [1,2,3];
var arr2 = [...arr];
// arr2 = [1,2,3]

3. 不使用Apply调用函数

在 ES5 中,要将包含两个数字的数组传递给 doStuff() 函数,您经常使用 Function.prototype.apply() 方法,如下所示:

function doStuff (x, y, z) {}
var args = [0, 1, 2];

// Call the function, passing args
doStuff.apply(null, args);

但是,通过使用扩展运算符,您可以将数组传递给函数。

doStuff(...args);

4. 解构数组

您可以根据需要将解构和其余运算符一起使用以将信息提取到变量中:

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
console.log(x); // 1
console.log(y); // 2
console.log(z); // { a: 3, b: 4 }

5.函数参数作为休息参数

ES6 也有三个点(...),表示一个剩余参数,它将函数的所有剩余参数收集到一个数组中。

function f(a, b, ...args) {
  console.log(args);
}

f(1, 2, 3, 4, 5); // [3, 4, 5]

6. 使用数学函数

任何使用 spread 作为参数的函数都可以被可以接受任意数量参数的函数使用。

let numbers = [9, 4, 7, 1];
Math.min(...numbers); // 1

7. 结合两个对象

您可以使用扩展运算符来组合两个对象。这是一种简单而干净的方法。

var carType = {
  model: 'Toyota',
  yom: '1995'
};

var carFuel = 'Petrol';

var carData = {
  ...carType,
  carFuel
}

console.log(carData);
// {
//  model: 'Toyota',
//  yom: '1995',
//  carFuel = 'Petrol'
// }

8. 将字符串分隔成单独的字符

您可以使用展开运算符将字符串展开为单独的字符。

let chars = ['A', ...'BC', 'D'];
console.log(chars); // ["A", "B", "C", "D"]

你可以想出更多使用Spread Operator的方法。我在这里列出的是它的流行用例。


P
Peter Mortensen

JavaScript 中的三个点是展开/休息运算符。

扩展运算符

spread syntax 允许在需要多个参数的地方扩展表达式。

myFunction(...iterableObj);

[...iterableObj, 4, 5, 6]

[...Array(10)]

休息参数

rest 参数语法用于具有可变数量参数的函数。

function(a, b, ...theArgs) {
  // ...
}

ES6 中引入了数组的展开/休息运算符。对象传播/休息属性有一个状态 2 proposal

TypeScript 还支持扩展语法,并且可以将其转换为带有次要 issues 的旧版本的 ECMAScript。


传播/休息现在是第 4 阶段,已完成。我认为包含在 ES9/2018 中github.com/tc39/proposal-object-rest-spread/blob/master/…
P
Peter Mortensen

这是 ES6 的一个特性,在 React 中也有使用。看下面的例子:

function Sum(x, y, z) {
   return x + y + z;
}
console.log(Sum(1, 2, 3)); // 6

如果我们最多有三个参数,这种方式很好。但是,如果我们需要添加例如 110 个参数怎么办。我们是否应该将它们全部定义并一一添加?

当然还有一种更简单的方法,叫做传播。而不是传递您编写的所有这些参数:

function (...numbers){} 

我们不知道我们有多少参数,但我们知道有很多参数。

基于ES6,我们可以将上面的函数重写如下,并利用它们之间的传播和映射,让它变得轻而易举:

let Sum = (...numbers) => {
    return numbers.reduce((prev, current) => prev + current);
}
console.log(Sum(1, 2, 3, 4, 5, 6, 7, 8, 9)); // 45

P
Peter Mortensen

向 Brandon Morelli 致敬。他完美地解释了 here,但链接可能会失效,所以我只是粘贴以下内容:

展开语法只是三个点: ... 它允许迭代在需要 0+ 个参数的地方展开。没有上下文就很难定义。让我们探索一些不同的用例来帮助理解这意味着什么。

示例 1 - 插入数组

看看下面的代码。在这段代码中,我们不使用展开语法:

变种中间 = [3, 4]; var arr = [1, 2, mid, 5, 6];控制台.log(arr);

上面,我们创建了一个名为 mid 的数组。然后我们创建第二个数组,其中包含我们的 mid 数组。最后,我们注销结果。您希望 arr 打印什么?点击上面的运行看看会发生什么。这是输出:

[1, 2, [3, 4], 5, 6]

这是你预期的结果吗?

通过将 mid 数组插入 arr 数组,我们最终得到了一个数组中的数组。如果这是目标,那很好。但是如果你只想要一个值为 1 到 6 的数组呢?为此,我们可以使用扩展语法!请记住,展开语法允许我们数组的元素展开。

让我们看看下面的代码。一切都一样 — 除了我们现在使用扩展语法将 mid 数组插入 arr 数组:

变种中间 = [3, 4]; var arr = [1, 2, ...mid, 5, 6];控制台.log(arr);

当你点击运行按钮时,结果如下:

[1, 2, 3, 4, 5, 6]

惊人的!

还记得你刚才读到的扩展语法定义吗?这就是它发挥作用的地方。如您所见,当我们创建 arr 数组并在 mid 数组上使用展开运算符时,mid 数组会展开,而不是仅仅被插入。这种扩展意味着 mid 数组中的每个元素都插入到 arr 数组中。结果不是嵌套数组,而是一个范围从 1 到 6 的数字数组。

示例 2 - 数学

JavaScript 有一个内置的数学对象,可以让我们进行一些有趣的数学计算。在此示例中,我们将查看 Math.max()。如果您不熟悉,Math.max() 会返回零个或多个数字中的最大值。这里有一些例子:

Math.max();
// -Infinity
Math.max(1, 2, 3);
// 3
Math.max(100, 3, 4);
// 100

可以看到,如果要求多个数的最大值,Math.max()需要多个参数。不幸的是,您不能简单地使用单个数组作为输入。在展开语法之前,对数组使用 Math.max() 的最简单方法是使用 .apply()

var arr = [2, 4, 8, 6, 0];函数 max(arr) { return Math.max.apply(null, arr); } console.log(max(arr));

它有效,它只是真的很烦人。

现在看看我们如何使用扩展语法做同样的事情:

var arr = [2, 4, 8, 6, 0]; var max = Math.max(...arr);控制台日志(最大);

无需创建函数并使用 apply 方法返回 Math.max() 的结果,我们只需要两行代码!扩展语法扩展了我们的数组元素并将我们数组中的每个元素单独输入到 Math.max() 方法中!

示例 3 - 复制一个数组

在 JavaScript 中,您不能通过将新变量设置为等于现有数组来复制数组。考虑以下代码示例:

var arr = ['a', 'b', 'c']; var arr2 = arr;控制台.log(arr2);

当您按下运行时,您将获得以下输出:

['a', 'b', 'c']

现在,乍一看,它似乎工作了——看起来我们已经将 arr 的值复制到了 arr2 中。但事实并非如此。你看,在 JavaScript 中处理对象(数组是一种对象)时,我们通过引用而不是值来分配。这意味着 arr2 已分配给与 arr 相同的引用。换句话说,我们对 arr2 所做的任何事情也会影响原始的 arr 数组(反之亦然)。看看下面:

var arr = ['a', 'b', 'c']; var arr2 = arr; arr2.push('d');控制台.log(arr);

上面,我们已经将一个新元素 d 推送到 arr2 中。然而,当我们注销 arr 的值时,您会看到 d 值也被添加到该数组中:

['a', 'b', 'c', 'd']

不过没必要害怕!我们可以使用扩展运算符!考虑下面的代码。和上面的差不多。但是,我们在一对方括号中使用了扩展运算符:

var arr = ['a', 'b', 'c']; var arr2 = [...arr];控制台.log(arr2);

点击运行,您将看到预期的输出:

['a', 'b', 'c']

上面,arr 中的数组值扩展为单独的元素,然后分配给 arr2。我们现在可以随意更改 arr2 数组,而不会对原始 arr 数组产生任何影响:

var arr = ['a', 'b', 'c']; var arr2 = [...arr]; arr2.push('d');控制台.log(arr);

同样,它起作用的原因是 arr 的值被扩展以填充我们的 arr2 数组定义的括号。因此,我们将 arr2 设置为等于 arr 的各个值,而不是像我们在第一个示例中所做的那样对 arr 的引用。

额外示例——字符串到数组

最后一个有趣的例子是,您可以使用扩展语法将字符串转换为数组。只需在一对方括号内使用展开语法:

var str = "你好"; var 字符 = [...str];控制台.log(字符);


P
Peter Mortensen

对于想要简单快速地理解这一点的人:

首先,这不仅仅是 React 的语法。这是来自 ES6 的称为 spread syntax 的语法,它迭代(合并、添加等)数组和对象。阅读有关它的更多信息here

所以回答这个问题:

假设你有这个标签:

<UserTag name="Supun" age="66" gender="male" />

你这样做:

const user = {
  "name"=>"Joe",
  "age"=>"50"
  "test"=>"test-val"
};

<UserTag name="Supun" gender="male"  {...user} age="66" />

然后标签将等于:

<UserTag name="Joe" gender="male" test="test-val" age="66" />

因此,当您在 React 标签中使用扩展语法时,它会将标签的属性作为对象属性与给定对象 user 合并(如果存在则替换)。此外,您可能已经注意到一件事,它只替换属性之前,而不是属性之后。所以在这个例子中,年龄保持不变。


最后不应该年龄= 50吗?
@DonCheadle 不,因为我在年龄之前添加了 {...user} 所以年龄标签不会替换
A
Alireza

它只是为您在 JSX 中以不同的方式定义道具!

它在 ES6 中使用 ... 数组和对象运算符(尚不完全支持对象一),因此基本上如果您已经定义了道具,则可以通过这种方式将其传递给您的元素。

所以在你的情况下,代码应该是这样的:

function yourA() {
  const props = {name='Alireza', age='35'};
  <Modal {...props} title='Modal heading' animation={false} />
}

所以你定义的道具现在分开了,可以在必要时重复使用。

它等于:

function yourA() {
  <Modal name='Alireza' age='35' title='Modal heading' animation={false} />
}

这些是 React 团队关于 JSX 中传播运算符的引用:

JSX 传播属性 如果您提前知道要放置在组件上的所有属性,那么使用 JSX 很容易:

var component = <Component foo={x} bar={y} />;

修改 Props 是不好的 如果您不知道要设置哪些属性,您可能会想稍后将它们添加到对象中:

var component = <Component />;
component.props.foo = x; // bad
component.props.bar = y; // also bad

这是一种反模式,因为这意味着我们无法帮助您检查正确的 propTypes 直到很久以后。这意味着您的 propTypes 错误以神秘的堆栈跟踪结束。道具应该被认为是不可变的。在其他地方改变 props 对象可能会导致意想不到的后果,因此理想情况下,此时它将是一个冻结的对象。传播属性 现在您可以使用 JSX 的一个新特性,称为传播属性:

var props = {};
    props.foo = x;
    props.bar = y;
    var component = <Component {...props} />;

你传入的对象的属性被复制到组件的 props 上。您可以多次使用它或将其与其他属性结合使用。规范顺序很重要。后面的属性会覆盖前面的属性。

var props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;
console.log(component.props.foo); // 'override'

奇怪的...符号是怎么回事? ES6 中的数组已经支持 ... 运算符(或扩展运算符)。还有一个关于 Object Rest 和 Spread 属性的 ECMAScript 提案。我们正在利用这些受支持和正在开发的标准,以便在 JSX 中提供更简洁的语法。


你已经回答完了他的问题。
什么是“道具”? “特性”?还是字面意思?
P
Peter Mortensen

三个点 ... 代表 spread operatorsrest parameters

它允许数组表达式或字符串或任何可以迭代的东西在需要零个或多个函数调用参数或数组元素的地方展开。

合并两个数组

var arr1 = [1,2,3]; var arr2 = [4,5,6]; arr1 = [...arr1, ...arr2];控制台.log(arr1); //[1, 2, 3, 4, 5, 6]

复制数组:

var arr = [1, 2, 3]; var arr2 = [...arr];控制台.log(arr); //[1, 2, 3]

注意:Spread 语法在复制数组时有效地深入一层。因此,它可能不适合复制多维数组,如下例所示(与 Object.assign() 和扩展语法相同)。

在特定索引处将一个数组的值添加到另一个数组,例如 3:

var arr1 = [4, 5] var arr2 = [1, 2, 3, ...arr1, 6] console.log(arr2); // [1, 2, 3, 4, 5, 6]

使用 new 调用构造函数时:

var dateFields = [1970, 0, 1]; // 1970 年 1 月 1 日 var d = new Date(...dateFields);控制台.log(d);

在对象文字中传播:

var obj1 = { foo: 'bar', x: 42 }; var obj2 = { foo: 'baz', y: 13 }; var clonedObj = { ...obj1 };控制台.log(克隆对象); // {foo: "bar", x: 42} var mergeObj = { ...obj1, ...obj2 };控制台.log(mergedObj); // {foo: "baz", x: 42, y: 13}

请注意,obj1 的 foo 属性已被 obj2 foo 属性覆盖。

作为一个剩余参数语法,它允许我们将不定数量的参数表示为一个数组:

function sum(...theArgs) { return theArgs.reduce((previous, current) => { return previous + current; }); } console.log(sum(1, 2, 3)); //6 console.log(sum(1, 2, 3, 4)); //10

注意:展开语法(除了展开属性的情况)只能应用于可迭代对象:

所以下面会报错:

var obj = {'key1': 'value1'}; var 数组 = [...obj]; // TypeError: obj 不可迭代

Reference1

Reference2


您使用三点合并两个数组的第一个示例非常有用。谢谢。
A
Andre Miras

对于那些来自 Python 世界的人来说,JSX 传播属性等同于 Unpacking Argument Lists(Python ** 运算符)。

我知道这是一个 JSX 问题,但使用类比有时有助于加快速度。


P
Peter Mortensen

...(扩展运算符)在 React 中用于:

提供一种简洁的方式将 props 从父组件传递到子组件。例如,给定父组件中的这些道具,

this.props = {
  username: "danM",
  email: "dan@mail.com"
}

它们可以通过以下方式传递给孩子,

<ChildComponent {...this.props} />

这与此类似

<ChildComponent username={this.props.username} email={this.props.email} />

但更清洁。


假设,如果我们只想将 'username' 属性传递给子组件,那么我们可以使用 吗?
为什么它要求我在 h1 标签中的这个关键字之前使用扩展运算符?类测试 { obj = { user1:“vijay”,年龄:27 }; m1() {

; } }
//ex-2:对于这个例子,当我使用 img 标签时,使用扩展运算符不会引发错误。类测试 { obj = { user1: "vijay", imageUrl: "picsum.photos/id/1/200/300" }; m1() { // <h1 {this.obj.user1}> </h1>; <img src={this.obj.imageUrl} />; } }
P
Peter Mortensen

三个点 (...) 称为扩展运算符,这在概念上类似于 ES6 数组扩展运算符,JSX 利用这些支持和开发的标准来在 JSX 中提供更清晰的语法

对象初始化器中的扩展属性将自己的可枚举属性从提供的对象复制到新创建的对象上。让 n = { x, y, ...z }; n; // { x: 1, y: 2, a: 3, b: 4 }

参考:

深入传播属性 JSX


这是关于 ECMAScript 中对象的扩展运算符的提议。问题是关于 JSX 扩展运算符。即使它们以相同的方式工作,它们也不相同。
@ivarni 感谢您带我进入上下文,给我一分钟,将根据问题上下文更新答案
@ivarni 根据上下文更新答案,希望这符合上下文
“三个点(...)被称为扩展运算符”只是不正确。 :-) Spread 和 rest 不是运算符,也不是,因为运算符必须产生单个结果值。 Spread 和 rest 是主要语法,而不是运算符。
M
Maximillian Laumeister

在 React 应用程序中传递 props 是一种常见的做法。在这样做时,我们能够将状态更改应用于子组件,无论它是纯的还是不纯的(无状态的或有状态的)。有时,在传递 props 时,最好的方法是传递单个属性或整个属性对象。由于 ES6 中对数组的支持,我们被赋予了“...”符号,因此我们现在能够实现将整个对象传递给子对象。

使用以下语法记录将道具传递给孩子的典型过程:

var component = <Component foo={x} bar={y} />;

当道具数量很少时使用它很好,但当道具数量变得太多时变得难以管理。当您不知道子组件中所需的属性时,此方法会出现问题,典型的 JavaScript 方法是简单地设置这些属性并稍后绑定到对象。这会导致 propType 检查问题和神秘的堆栈跟踪错误,这些错误无用并导致调试延迟。以下是这种做法的一个例子,以及不应该做的事情:

var component = <Component />;
component.props.foo = x; // bad
component.props.bar = y;

可以实现相同的结果,但通过这样做可以获得更适当的成功:

var props = {};
props.foo = x;
props.bar = y;
var component = Component(props); // Where did my JSX go?

但不使用 JSX spread 或 JSX,因此将其循环回方程,我们现在可以执行以下操作:

var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;

"...props" 中包含的属性是 foo: x, bar: y。这可以与其他属性结合使用以下语法来覆盖“...props”的属性:

var props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;
console.log(component.props.foo); // 'override'

此外,我们可以将其他属性对象相互复制或以这种方式组合它们:

var oldObj = { foo: 'hello', bar: 'world' };
var newObj = { ...oldObj, foo: 'hi' };
console.log(newObj.foo); // 'hi';
console.log(newObj.bar); // 'world';

或者像这样合并两个不同的对象(这在所有 React 版本中尚不可用):

var ab = { ...a, ...b }; // merge(a, b)

根据 Facebook 的 react/docs 网站,另一种解释方式是:

如果您已经将“props”作为对象,并且想在 JSX 中传递它,则可以使用“...”作为 SPREAD 运算符来传递整个 props 对象。下面两个例子是等价的:

function App1() {
  return <Greeting firstName="Ben" lastName="Hector" />;
}



function App2() {
  const props = {firstName: 'Ben', lastName: 'Hector'};
  return <Greeting {...props} />;
}

当您构建通用容器时,展开属性会很有用。但是,它们也可以通过轻松将许多不相关的道具传递给不关心它们的组件来使您的代码变得混乱。应谨慎使用此语法。


“纯”和“不纯”是字面意思吗?为了强调,我们在这个平台上有斜体和粗体。
P
Peter Mortensen

它在 JavaScript 中称为传播语法。

它用于在 JavaScript 中解构数组或对象。

例子:

const objA = { a: 1, b: 2, c: 3 }
const objB = { ...objA, d: 1 }
/* Result of objB will be { a: 1, b: 2, c: 3, d: 1 } */
console.log(objB)

const objC = { ....objA, a: 3 }
/* result of objC will be { a: 3, b: 2, c: 3, d: 1 } */
console.log(objC)

您可以使用 JavaScript 中的 Object.assign() 函数执行相同的结果。

参考:传播syntax


P
Peter Mortensen

ECMAScript 6 (ES6) 中引入的扩展运算符(三元运算符)。 ECMAScript (ES6) 是 JavaScript 的包装器。

props 中的扩展运算符可枚举属性。

this.props = { firstName: 'Dan', lastName: 'Abramov', city: 'New York', country: 'USA' }

{...this.props} = { firstName:'Dan',lastName:'Abramov',城市:'New York',国家:'USA' }

但主要特征扩展运算符用于引用类型。

例如,

let person= {
    name: 'Alex',
    age: 35
}
person1 = person;

person1.name = "Raheel";

console.log( person.name); // Output: Raheel

这称为引用类型。一个对象会影响其他对象,因为它们在内存中是可共享的。如果您独立获取一个值,则意味着扩展内存并且都使用扩展运算符。

 let person= {
        name: 'Alex',
        age: 35
    }
person2 = {...person};

person2.name = "Shahzad";

console.log(person.name); // Output: Alex

R
Ramesh R

传播运算符!由于大多数人已经优雅地回答了这个问题,我想建议一个使用扩展运算符的快速列表:

... 扩展运算符可用于 JavaScript 中的许多不同常规任务,包括以下内容:

复制数组

连接或组合数组

使用数学函数

使用数组作为参数

将项目添加到列表

在 React 中添加状态

组合对象

将 NodeList 转换为数组

查看文章了解更多详情。 How to use the Spread Operator. 我建议习惯它。有很多很酷的方法可以使用扩展运算符。


R
Ramesh R

这 3 个点 ... 不是 React 术语。这些是 JavaScript ES6 扩展运算符。这有助于在不干扰原始数组的情况下创建一个新数组来执行深层复制。这也可以用于对象。

const arr1 = [1, 2, 3, 4, 5]
const arr2 = arr1 // [1, 2, 3, 4, 5]
/*
 This is an example of a shallow copy.
 Where the value of arr1 is copied to arr2
 But now if you apply any method to
 arr2 will affect the arr1 also.  
*/

/*
 This is an example of a deep copy. 
 Here the values of arr1 get copied but they 
 both are disconnected. Meaning if you
 apply any method to arr3 it will not
 affect the arr1.
 */
 const arr3 = [...arr1] // [1, 2, 3, 4, 5]

R
Ramesh R

... 3 个点代表 JS 中的展开运算符。

没有展开运算符。

let a = ['one','one','two','two'];
let unq = [new Set(a)];

console.log(a);
console.log(unq);

输出:

(4) ['one', 'one', 'two', 'two']
[Set(2)]

使用扩展运算符。

let a = ['one','one','two','two'];
let unq = [...new Set(a)];

console.log(a);
console.log(unq);

输出:

(4) ['one', 'one', 'two', 'two']
(2) ['one', 'two']

P
Paras Buda

扩展语法允许像数组和对象这样的数据结构对它们进行解构,以便从中提取值或向它们添加值。例如,上面示例中的 const obj={name:"ram",age:10} const {name}=obj 我们可以说我们解构了 obj 并从该对象中提取了名称。同样,在此示例中的 const newObj={...obj,address:"Nepal"} 我们为该对象添加了一个新属性。这在数组的情况下也是类似的。


P
Peter Mortensen

这些被称为点差。顾名思义,这意味着它将它的任何值放入那些数组或对象中。

如:

let a = [1, 2, 3];
let b = [...a, 4, 5, 6];
console.log(b);
> [1, 2, 3, 4, 5, 6]

A
Abhishek3301

Spread 运算符允许您将对象、字符串或数组之类的可迭代对象扩展为其元素,而 Rest 运算符通过将一组元素缩减为一个数组来执行相反的操作。