React.js 给组件属性赋值的展开运算符应该怎么理解?

创建一个组件然后渲染到页面上:

class person extends React.Component{

    constructor(name,age)
    {
        this.name = name;
        this.age = age;
    }
    
   
    render(){
       return( <div>{this.props.name}--{this.props.age}</div>);
    }

}

const data = {
     name:'张三',
     age:12
}


ReactDom.render(<Person {...data}></Person>,document.getElementById('app') )

我的问题是,
...代表展开运算符,在这里我的理解 ...data 相当于把data给解构赋值了吧?,
如果是解构赋值的话,

ReactDom.render(<Person { "name":"张三","age":12 }></Person>,document.getElementById('app') )

,这样写为什么会报错呢?

   <Movie name={user.name} age={user.age} gender={user.gender}></Movie>

非要这样写才正确... 这里很迷惑,不知道这个'...'符号到底做了什么,

阅读 6.2k
4 个回答

把 JSX 转化一下容易理解

const data = {
  name: '张三',
  age: 12
}
<Person name={data.name} age={data.age}></Person>

const element = {
  elementName: 'Person',
  props: {
    name: data.name,
    age: data.age
  }
};

{...data}相当于

<Person {...data}></Person>

const element = {
  elementName: 'Person',
  props: {
    ...data
  }
};

因为这里并不是标准的 js 语法啊。

那么既然不标准,React 想让 {...data} 映射到(包括但可以不限于)下面两种模式:

  • {key1: val1, key2: val2, ...}
  • key1={data.val1} key2={data.val2} ...

哪一种都是它说了算,毕竟这个地方是 <Person ...>...</Person> 这个JSX 的地盘。

那么对于 JSX 来说,显然第二种才是符合它的语法的。

这是es6的rest语法。比如这样写

function callMe(...allArgs) {
  console.log(allArgs); // [1, 2, 3];
}

callMe(1, 2, 3);

callMe的参数用了rest语法,代表allArgs要收集所有剩下的参数,并且变成一个数组,
再看一个:

function callMe(a, ...allArgs) {
  console.log(allArgs); // [2, 3];
}

callMe(1, 2, 3);

allArgs只收集了两个参数,因为第一个参数被a拿走。

我们再来看下解构

function callMe(a, b, c) {
  console.log(a, b, c); // 1 2 3;
}

const arr = [1, 2, 3];
callMe(...arr);

调用callMe时,用了rest语法,数组的值都会被分解成各个参数。

而你提供的也是解构,但是不是这种形式:

// 原句
data = {name: "张三", age: 12};
<Person {...data}></Person>

// 相等于
<Person name={data.name} age={data.age}></Person>

这里是JSX的语法规范, 不是es6的rest。
比如: <View {...a, b: 1}/> 这样的写法是错误的。

编译打包的时候<View {...a}/> babel先将其转化AST形式,如下:

{
    "type": "JSXSpreadAttribute",
    "argument": {
         "type": "Identifier",
         "name": "a"
    }
}

babel 处理这个AST,生成如下js代码

React.createElement(View, a);
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题