ReactJS将每个文本节点的字母包装在一个单独的范围内。为什么?

时间:2015-07-09 09:20:03

标签: reactjs

我有一个反应组件,它的部分状态如下:

<span className="filter-name">{ selectedText }</span>

但是,我得到以下内容,而不是带有文字的<span>。为什么呢?

selectedText生成如下:

let selectedText = this.state.selected.map ( ( id ) => 
  this.locationsById[ id ].formalname ).join ( ", " ).
  trunc (this.maxTitleLength );

locationsById是一组对象。 formalname是一个字符串属性。 trunc的实现方式如下:

"use strict";
String.prototype.trunc = function( n, useWordBoundary ) {
    var tooLong = this.length > n,
        s_ = tooLong ? this.substr ( 0, n - 1 ) : this;
    s_ = useWordBoundary && tooLong ? s_.substr ( 0, s_.lastIndexOf ( " " ) ) : s_;
    return tooLong ? s_ + "…" : s_;
};

React生成的结果如下所示:

<span class="filter-name" data-reactid=".5.0.0">
<span data-reactid=".5.0.0.0:0">Р</span>
<span data-reactid=".5.0.0.0:1">о</span>
<span data-reactid=".5.0.0.0:2">с</span>
<span data-reactid=".5.0.0.0:3">с</span>
<span data-reactid=".5.0.0.0:4">и</span>
<span data-reactid=".5.0.0.0:5">я</span>
<span data-reactid=".5.0.0.0:6">,</span>
<span data-reactid=".5.0.0.0:7"> </span>
<span data-reactid=".5.0.0.0:8">М</span>
<span data-reactid=".5.0.0.0:9">о</span>
<span data-reactid=".5.0.0.0:a">с</span>
<span data-reactid=".5.0.0.0:b">к</span>
<span data-reactid=".5.0.0.0:c">о</span>
<span data-reactid=".5.0.0.0:d">в</span>
<span data-reactid=".5.0.0.0:e">с</span>
<span data-reactid=".5.0.0.0:f">к</span>
<span data-reactid=".5.0.0.0:g">а</span>
<span data-reactid=".5.0.0.0:h">я</span>
<span data-reactid=".5.0.0.1"> </span>

在将trunc() selectedText作为Россия转储到控制台之前,没有任何类型引用。在trunc()后,它变为

String 0: "Р"1: "о"2: "с"3: "с"4: "и"5: "я"length: 6__proto__: String[[PrimitiveValue]]: "Россия"

1 个答案:

答案 0 :(得分:1)

首先:不要修改String.prototype!坏事将会发生。

不知何故,你最终得到了一个String对象,比如new String('foo')

> typeof new String('foo')
'object'
> Object.keys(new String('foo'))
[ '0', '1', '2' ]

它会消失,但是当你把React作为一个孩子的对象时,它会将这些键解释为key,所以它们是相同的:

<div>{{foo: <span>bar</span>}}</div>
<div><span key="foo">bar</span></div>

当您将React文本作为子项提供时,它会将其包装在一个范围内。因此,它会看到一个带有键'0','1','2',...和字符串值的对象,因此它将每个对象渲染为带有数字键的跨度。

我不确定为什么你有一个String对象,但是String(that)会给你一个普通的字符串。

<span className="filter-name">{ String(selectedText) }</span>

并重申:不要修改原生原型,包括String.prototype,Array.prototype,Object.prototype等!