天道酬勤,学无止境

reactjs中的传播语法“...this.props”感觉很奇怪(spread syntax "...this.props" in reactjs feels odd)

问题

使用扩展运算符对 JSX 中的props对象做出反应似乎没有输出我期望的内容。

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

似乎被渲染成style="foo" ,它应该是style:"foo"记录在这里。 我在任何地方都找不到这个文档。 我对反应完全陌生,我正在尝试理解语法并想知道反应是否在内部执行了这样的未记录的事情。

一个简单的测试突显了我的困惑:

const x = {...{test:1}}.test;
alert(x);

被警告

1

这肯定不会编译:

<Text test: 1 />
回答1

这在此处的 React 文档中有所记录。

要在此处复制粘贴,它指出:

如果你已经有 props 作为对象,并且你想在 JSX 中传递它,你可以使用 ... 作为“传播”操作符来传递整个 props 对象。

它是完全有效的、记录在案的 JSX。

此外,它们提供了将 props 传递给组件的两种不同方法的示例——一种作为离散属性,一种作为传播对象——并注意,就接收 props 的组件而言,它们是相同的:

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

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

将此扩展到上面的示例,您可以将这两个视为等效:

function App1() {
    return <Text test={1} />;
}

function App2() {
    const props = {test: 1};
    return <Text {...props} />;
}

至于它在引擎盖下如何工作的细节,请记住这是一个转译,所以我们不需要过多关注它在引擎盖下的工作方式——只要你知道它们是等价的,一个是“捷径”,你应该没问题。

还值得注意的是,文档规定应该谨慎使用传播方法,因为“传播属性可能很有用,但它们也很容易将不必要的 props 传递给不关心它们的组件,或者将无效的 HTML 属性传递给多姆。”

希望这有助于为您澄清事情!

回答2

解构从对象中提取键值对。

看看这个例子

const obj = {
  a: 'a',
  b: 'b'
}

现在,解构obj将导致

const { a, b } = obj;
console.log(a);  // 'a'
console.log(b);  // 'b'

如果你在作为 React 组件的 props 传递时解构了一个对象,就会发生这种情况

<Component {...obj} />

这将在内部转换为

<Component a={a} b={b} />

因此,如果您将样式作为道具传递给组件,则应该这样做

const style = {
  background:'yellow'
} 

<Component style={style} />

或者

const obj = {
  style = {
      background:'yellow'
    } 
}

<Component {...obj} />

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • React中的这三个点是做什么的?(What do these three dots in React do?)
    问题 ...在此React(使用JSX)代码中做什么?它叫什么? <Modal {...this.props} title='Modal heading' animation={false}> 回答1 那是财产传播符号。 它是在ES2018中添加的(用于数组/可迭代对象的版本更早于ES2015),但是它在React项目中已经通过翻译长期得到了支持(作为“ JSX传播属性”,即使您也可以在其他地方这样做) )。 {...this.props}将props的“自己的”可枚举属性散布为要创建的Modal元素上的离散属性。 例如,如果this.props包含a: 1和b: 2 ,则 <Modal {...this.props} title='Modal heading' animation={false}> 将与 <Modal a={this.props.a} b={this.props.b} title='Modal heading' animation={false}> 但是它是动态的,因此包含了props中任何“自己的”属性。 由于children是props的“自有”财产,因此传播将包括它。 因此,如果出现此组件的组件具有子元素,则将它们传递给Modal 。 在开始标签和结束标签之间放置子元素只是语法上的糖(一种很好的选择),用于将children属性放置在开始标签中。 例子:
  • Babel 7 和 webpack 4 不适用于数组中的条件扩展操作[短路语法](Babel 7 and webpack 4 not working for Conditional spread operation in Array[Short circuit syntax])
    问题 我遇到了一个奇怪的问题,从我使用 stage-0 的先前版本升级到 Babel 7 后,短路语法不起作用,并且它没有任何问题 不工作: ...isCSCProfile && [{ isComplete: progressbarStates[3] === PROGRESS_BAR_SUCCESS, messageKey: commonOrderMessages.service_request_header, link: "serviceRequest-header" }], 作品: ...(isCSCProfile ? [{ isComplete: progressbarStates[3] === PROGRESS_BAR_SUCCESS, messageKey: commonOrderMessages.service_request_header, link: "serviceRequest-header" }] : []), 我在 webpack 中包含了 Babel-Polyfill 插件,我正在测试最新的 chrome 版本 所以问题是我应该包含哪个插件才能使其工作而无需更改代码 回答1 我假设isCSCProfile是布尔值。 如果isCSCProfile为假,那么你试图在第一种情况下传播一个布尔值,这是行不通的。 在深入研究之后,似乎我错了传播语法不适用于布尔值。
  • 是传播“语法”还是传播“运算符”?(Is it spread “syntax” or the spread “operator”?)
    问题 我听说...被称为“扩展语法”和“扩展运算符”,后者更受欢迎。 有关MDN文档的URL表明,它最初被称为“扩展运算符”,但后来更改为“扩展语法”,而MDN的运算符列表中并未提及它。 Google似乎建议术语“运营商”更受欢迎和接受,例如Microsoft文档和es6-features.org等网站都将其称为“运营商” 。 在ECMAScript的上下文中,哪一个术语最正确(如果有的话),为什么? 数组销毁分配又如何呢? 回答1 它不是运算符。 从这个词的所有意义上讲,它不是一个。 自引入以来,这一直是一个巨大的误解,尽管受到了大众的欢迎-这不是一个错误,并且有几点客观要点: 它不符合运算符的定义不能用作运算符语言规范暗示它不是运算符 应该提到的是,传播语法具有不同的“风味”,在不同的上下文中使用,并且在使用相同的标点符号时通常以不同的名称进行引用。 传播语法基本上是...标点符号的一个概括性术语,请参见Felix Kling的出色答案,详细介绍了所有用法和名称。 关于这些个人用途的更多解释在补充答案中给出。 什么是运算符? 从语义上讲,在ECMAScript上下文中,运算符只是内置函数,这些函数接受参数并求值为单个值-以前缀,中缀或后缀表示法编写,通常使用诸如+或/符号名。 从维基百科: 简而言之,以某种方式对涉及运算符的表达式进行求值,结果值可能只是一个值(一个r值)
  • 传播语法ES6(Spread Syntax ES6)
    问题 考虑以下示例代码 var x = ["a", "b", "c"]; var z = ["p", "q"]; var d = [...x, ...z]; var e = x.concat(z); 此处, d和e的值完全相同,并且等于["a", "b", "c", "p", "q"] ,因此, 两者之间到底有什么区别? 哪一个效率更高?为什么? 传播语法的确切用途是什么? 您是否不认为以正式的广泛语言引入这些小捷径可能会留下一些未被注意的错误,我的意思是说这要么是不必要的,要么是我没有意识到它的适当性。 回答1 在给出的示例中,两者之间基本上没有区别 .concat效率显着提高:http: .concat因为... (spread)仅是更基础的基础语法之上的语法糖,该基础语法显式地遍历索引以扩展索引。大批。 Spread允许在更笨拙的直接数组操作之上添加加糖语法 为了在上面的#3上进行扩展,您使用点差是一个有些人为的示例(尽管很可能会经常出现在野外)。 当(例如)参数列表的整体应传递给函数主体中的.call时, .call很有用。 function myFunc(){ otherFunc.call( myObj, ...args ); } 相对 function myFunc(){ otherFunc.call( myObj, args[0], args[1], args[2]
  • 对象传播与Object.assign(Object spread vs. Object.assign)
    问题 假设我有一个options变量,并且想要设置一些默认值。 这两种选择的优点/缺点是什么? 使用对象传播 options = {...optionsDefault, ...options}; 或使用Object.assign options = Object.assign({}, optionsDefault, options); 这就是让我感到奇怪的承诺。 回答1 这并不一定是详尽无遗的。 传播语法 options = {...optionsDefault, ...options}; 好处: 如果编写代码以在没有本机支持的环境中执行,则可以仅编译此语法(与使用polyfill相对)。 (例如,使用Babel。) 不太冗长。 缺点: 最初编写此答案时,这只是一个建议,而不是标准化的。 在使用投标时,请考虑一下如果现在用它编写代码会做什么,并且在朝着标准化的方向发展时,它不会变得标准化或更改。 此后已在ES2018中标准化。 从字面上看,不是动态的。 Object.assign() options = Object.assign({}, optionsDefault, options); 好处: 标准化。 动态的。 例子: var sources = [{a: "A"}, {b: "B"}, {c: "C"}]; options = Object.assign.apply
  • 难以理解JSX传播运算符(Trouble understanding JSX spread operator)
    问题 在React文档中给出以下示例代码: var props = {}; props.foo = x; props.bar = y; var component = <Component {...props} />; 我做了一些调查...props实际评估的结果是这样的: React.__spread({}, props) 依次求值为{foo: x, bar: y} 。 但是我想知道的是,为什么我不能这样做: var component = <Component props />; 我看不出点差运算符的含义是什么。 回答1 这有助于使您的代码更简洁-由于props是一个对象,所以散布运算符会采用您传入的对象的属性并将其应用于组件。 因此,该Component的属性将为foo ,其值为x以及一个bar的值为y 。 它将与以下内容相同: var component = <Component foo={props.foo} bar={props.bar} />; 短一点 回答2 在reactpatterns.com上发布了关于对象剩余分布语法如何与react一起工作的最佳概述之一: JSX传播属性传播属性是JSX的功能。 它是一种语法糖,用于将对象的所有属性作为JSX属性传递。 这两个例子是等效的。 // props written as attributes <main
  • ECMAScript 6在对象解构中传播语法。 在TypeScript和Babel中的支持(ECMAScript 6 spread syntax in object deconstruction. Support in TypeScript and Babel)
    问题 以下有效的ECMAScript 6是否有效? 最新版本的Babel支持它,但TypeScript不支持。 我找不到处理这种情况的任何ES6参考。 var a = { foo : 'foo' }; var b = { ...a }; 回答1 不,这不是有效的ECMAScript6。ES6仅支持函数参数和数组解构中的rest语法,以及函数调用和数组构造中的扩展语法。 最新版本的Babel支持它 Babel确实将objectRestSpread ES7建议实施为实验性插件。 您不应该使用此功能,它可能会随时中断。 回答2 TypeScript 2.1确实支持此功能。 这里 回答3 我犯了以下错误 const o = { p : { q:1, r:2 } }; const {{q,r}} = o; 后来才知道,这是直接对我很重要q和r从P,所以它基本上是在我的情况下,语法错误,所以纠正代码语法如下。 const {p:{q,r,s=9}} = o; console.log(q,r,s); // 1,2,9
  • spread syntax "...this.props" in reactjs feels odd
    Using the spread operator in react with objects like props within JSX seems not to output what I expect. <Text {...this.props} /> seems to be rendered into style="foo", where it should be style:"foo" as documented here. I couldn't find this documented anywhere. I'm totally new to react and I'm trying to understand the syntax and wonder if react does undocumented stuff like this internally. A simple test just underlined my confusion: const x = {...{test:1}}.test; alert(x); alerted 1 And this for sure doesn't compile: <Text test: 1 />
  • ReactJS:当子组件调用父组件时,“this.props”不是函数(ReactJS: “this.props” is not a function when child component calls parent)
    问题 我已经编写了这段代码,目前正在处理 onClick 事件中的错误。 我有两个事件,子元素上的 onClick 事件和顶级父元素上的 onChange 事件。 预期的行为应该是更改当前保存在 Container 组件中的 activeAccount 变量。 为此,我在 AccountRow 组件上添加了一个 onClick 处理程序,然后该处理程序应该调用顶级父级的 onChange 函数。 然而,该行 'this.props.onChange(this.props.account)', 在 handleClick: function(e) { this.props.onChange(this.props.account); }, 意味着使用参数“this.props.account”调用父函数, 给我这个错误: Uncaught TypeError: this.props.onChange is not a function. 我最初认为这是一个范围问题,但我添加了 {...this.props} 在父容器组件中的每个子项和嵌套子项上。 因此,所有道具都应该向下传播到 AccountRow 组件。 尽管如此,问题仍然存在。 var ACCOUNTS = [ {name: 'cash on hand'}, {name: 'savings account'}, {name:
  • ReactJS中“ this”之谜(Mystery of “this” in ReactJS)
    问题 我对Facebook的React世界还很陌生。 他们的文档似乎非常好,但是在某些方面我需要稍微澄清一下。 这就是其中之一。 Src:http://tuts-javascript.appspot.com/reactjs-add-remove-table-row var CompanyApp = React.createClass({ getInitialState: function() { return {companylist:this.props.companies}; }, handleNewRowSubmit: function( newcompany ) { this.setState( {companylist: this.state.companylist.concat([newcompany])} ); }, handleCompanyRemove: function( company ) { var index = -1; var clength = this.state.companylist.length; for( var i = 0; i < clength; i++ ) { if( this.state.companylist[i].cname === company.cname ) { index = i; break; } } this
  • 使用哪种ReactJS语法; React.createClass或ES6扩展了吗?(Which ReactJS syntax to use; React.createClass or ES6 extends?)
    问题 我是ReactJS的初学者。 我在各种网站上学习和研究了很多文档和电子书。 我意识到ReactJS有两种语法。 例子: React.createClass({ displayName: 'Counter', getDefaultProps: function(){ return {initialCount: 0}; }, getInitialState: function() { return {count: this.props.initialCount} }, propTypes: {initialCount: React.PropTypes.number}, tick() { this.setState({count: this.state.count + 1}); }, render() { return ( <div onClick={this.tick}> Clicks: {this.state.count} </div> ); } }); 这个版本是由ES6编写的: class Counter extends React.Component { static propTypes = {initialCount: React.PropTypes.number}; static defaultProps = {initialCount: 0}
  • 如何将所有其他道具传递给反应类?(How to pass all other props to react class?)
    问题 假设我有 3 个基于类的组件需要并实现的道具,即 <Component propOne={this.props.one} propTwo={this.props.two}> {this.props.children} </Component> 我将如何传递我最初不期望的任何其他道具,但说使用我的组件的其他人想要使用? 我刚在想 <Component propOne={this.props.one} propTwo={this.props.two} {...this.props} > {this.props.children} </Component> 但我担心道具重复 回答1 使用扩展运算符 const {propOne, propTwo, ...leftOver} = this.props; // `leftOver` contains everything except `propOne` and `propTwo` 所以你的例子会变成: const {propOne, propTwo, children, ...props} = this.props; <Component propOne={propOne} propTwo={propTwo} {...props}> {children} </Component> 回答2 过滤它们? function without
  • ES6 JS 中的 spread 语法如何作为函数参数工作?(How does the spread syntax in ES6 JS work as a function argument?)
    问题 好的,所以我试图了解新的价差如何作为函数参数工作。 想象一个具有未知数量参数的函数并将它们加在一起。 let addNums = ...a => a.reduce ((a,b) => a+b); 这个功能显然有效。 那么,我的问题是什么? 好吧,这是一些观察结果,然后是我的问题: 作为函数参数/参数的传播语法似乎旨在将一组值作为单独的参数“传播”: 根据我所做的研究,spread 语法可用于将数组传递给不接受数组作为标准参数的函数,例如 Array.prototype.push(),而不必使用apply : var x = []; var y = [1,2,3]; // where Array.push(arg1,arg2,...) requires separate arguments this is now possible: x.push(...y); // which 'spreads' 'y' into separate arguments: x.push (arg1,arg2,...) 但是在这种情况下传递给push的 Array 需要事先声明/定义(在这种情况下y ) 这是通过查看函数内部参数对象的长度来确认的 如果我使用addNums(1,2,3,4) , arguments.length仍然是 == 4。所以,似乎该函数也仍然被称为addNums(1,2,3
  • Reactjs中{…this.props}的含义是什么(What is the meaning of {…this.props} in Reactjs)
    问题 的意义是什么 {...this.props} 我正在尝试那样使用它 <div {...this.props}> Content Here </div> 回答1 它被称为传播属性,其目的是使道具的传递更加容易。 让我们假设您有一个接受N个属性的组件。 如果数量增加,将这些信息传递下去可能是乏味且笨拙的。 <Component x={} y={} z={} /> 因此,相反,您可以这样做,将它们包装在一个对象中并使用扩展符号 var props = { x: 1, y: 1, z:1 }; <Component {...props} /> 它将把它解压缩到组件上的props中,即,仅当将props向下传递到另一个组件时,您才“永远”不要在render()函数内使用{... props} 。 像通常this.props.x一样使用打开包装的道具。 回答2 这是ES6 Spread_operator和Destructuring_assignment。 <div {...this.props}> Content Here </div> 等于Class Component const person = { name: "xgqfrms", age: 23, country: "China" }; class TestDemo extends React.Component {
  • ReactJS中的三个点是做什么的(What does three dots do in ReactJS [duplicate])
    问题 这个问题已经在这里有了答案: React中的这三个点是做什么的? (29个答案) 4年前关闭。 const peopleList = this.state.people.map( x => { return <Person key={x.name} {...x} /> }) 此代码“ {... x}”是什么意思? 回答1 这是react中的散布运算符语法。 从MDN DOCS : 扩展语法允许在需要多个参数(用于函数调用)或多个元素(用于数组文字)或多个变量(用于解构赋值)的地方扩展表达式。 在您的情况下<Person key={x.name} {...x} />这意味着将x包含的整个对象或属性作为道具发送给Person Component 例如,如果 var x = { name: "Hello", last_name: "World" } 然后,如果您执行<Person key={x.name} {...x} /> 以上将等同于 <Person key={x.name} name={x.name} last_name={x.last_name}/> 扩展语法与道具一起使用的顺序也很重要。 考虑将道具传递给类似这样的组件的情况 var data = { name: 'abc', age: '25', college: 'lmit' } 并且如果您使用传播运算符语法,例如
  • ReactJS:webpack:无法使用扩展语法进行编译(ReactJS: webpack: Failed to compile with spread syntax)
    问题 我想告诉你我的问题。 我的环境: Node: 8.9.1 npm: 5.6.0 yarn: 1.3.2 包.json "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-plugin-transform-object-rest-spread": "^6.26.0", "babel-preset-env": "^1.6.1", "babel-preset-react": "^6.24.1", "copy-webpack-plugin": "^4.1.1", ... "webpack": "^3.7.1", "webpack-dev-server": "^2.9.2" }, webpack.config.js ... module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { cacheDirectory: true, presets: ['react', 'env'] } } }, ... 它总是编译失败,就像 {...} ./src/flux/components/BaseComponent.js 模块构建失败
  • 节点 5.10 扩展运算符不起作用(Node 5.10 spread operator not working)
    问题 根据文档,最新的节点(节点 5+)应该默认支持扩展运算符,如下所示: const newObj = { ...oldObj, newProperty: 1 } 我已经安装了节点 5.10.1(例如,这就是“node -v”告诉我的)。 但我仍然收到此错误: c:\[myprojectfolder]>node index.js c:\[myprojectfolder]\index.js:21 ...oldObj, ^^^ SyntaxError: Unexpected token ... at exports.runInThisContext (vm.js:53:16) at Module._compile (module.js:387:25) at Object.Module._extensions..js (module.js:422:10) at Module.load (module.js:357:32) at Function.Module._load (module.js:314:12) at Function.Module.runMain (module.js:447:10) at startup (node.js:146:18) at node.js:404:3 我错过了什么? 回答1 支持数组扩展语法,但不支持对象扩展语法——这很可能是因为它尚未最终确定为
  • ECMAScript文档中的SpreadElement是什么? 它与MDN的Spread语法相同吗?(What is SpreadElement in ECMAScript documentation? Is it the same as Spread syntax at MDN?)
    问题 在ECMAScript规范中,描述了SpreadElement SpreadElement[Yield]: ...AssignmentExpression[In, ?Yield] 这与Spread语法相同吗 扩展语法允许将可迭代程序(例如数组表达式或字符串)扩展到期望零个或多个参数(用于函数调用)或元素(用于数组文字)的位置,或将对象表达式扩展在零个或多个位置键值对(用于对象文字)是必需的。 句法对于函数调用: myFunction(...iterableObj); 对于数组文字: [...iterableObj, 4, 5, 6] 在MDN文档中有描述? SpreadElement和/或spread语法的用例是什么? 如果SpreadElement和spread语法不同,它们在哪些特定方式上有所不同? 回答1 术语“散布算子”是一种“伞词”,指的是ES6中看起来像...x各种语法构造。 MDN也是一样。 但是,这是错误的,因为...不是运算符(至少在ECMAScript规范使用术语“运算符”的意义上不是这样)。 它不会生成可用于进一步计算的值。 我宁愿把它比作其他标点符号,如,或; (它们也是相关的,但在不同的上下文中具有不同的含义)。 术语“扩展运算符”可以指: 扩展元素,var arr = [a,b,... c] ;:扩展元素将可迭代( c )扩展为新数组。 等效于[a
  • 解构对象并忽略结果之一(Destructuring object and ignore one of the results)
    问题 我有: const section = cloneElement(this.props.children, { className: this.props.styles.section, ...this.props, }); 在this.props ,我有一个我不想传递给克隆元素的styles属性。 我能怎么做? 回答1 您可以使用对象休息/传播语法: // We destructure our "this.props" creating a 'styles' variable and // using the object rest syntax we put the rest of the properties available // from "this.props" into a variable called 'otherProps' const { styles, ...otherProps } = this.props; const section = cloneElement(this.props.children, { className: styles.section, // We spread our props, which excludes the 'styles' ...otherProps, })
  • Array.from() 与传播语法(Array.from() vs spread syntax)
    问题 使用Array.from(document.querySelectorAll('div'))或[...document.querySelectorAll('div')]之间有什么区别吗? 下面是一个例子: let spreadDivArray = [...document.querySelectorAll('div')]; console.log(spreadDivArray); let divArrayFrom = Array.from(document.querySelectorAll('div')); console.log(divArrayFrom); console.log()将记录相同的结果。 有什么性能差异吗? 回答1 Spread元素(它不是运算符)仅适用于可迭代的对象(即实现@@iterator方法)。 Array.from()也适用于不可迭代的类数组对象(即具有length属性和索引元素的对象)。 看这个例子: const arrayLikeObject = { 0: 'a', 1: 'b', length: 2 }; // This logs ['a', 'b'] console.log(Array.from(arrayLikeObject)); // This throws TypeError: arrayLikeObject[Symbol