React js:与其他元素相比,输入元素呈现不同
React js: Input element renders differently compared to other elements
我制作了一个简单的应用程序(在 React js 中),它有两个列表,您可以向该列表添加元素。一个是输入元素列表,另一个是跨度列表。
添加新元素后,span 列表呈现完美,但 input 列表呈现不同。
这就是我的反应 class 的样子
var App = React.createClass({
getInitialState: function(){
return {
'app': {
'data': this.props.data,
'data2': this.props.data2
}
};
},
onclick: function(){
var dat = this.state.app.data;
var val = this.refs.input.getDOMNode().value;
dat.splice(0, 0, val);
var dat2 = this.state.app.data2;
dat2.splice(0, 0, val);
this.setState({'app': {
'data': dat,
'data2': dat2
}});
},
renderElement: function(i){
return(
<input defaultValue={i} />
);
},
renderElement2: function(i){
return(
<span>{i}</span>
);
},
render: function(){
var self = this;
return(
<div>
<input type="text" ref="input" placeholder="Enter a value"/>
<input type="button" value="Add value" onClick={this.onclick} />
<div className="col2">
{this.state.app.data.map(function(page, i){
return(
<div key={i}>{self.renderElement(page)}</div>
);
})}
</div>
<div className="col2">
{this.state.app.data2.map(function(page, i){
return(
<div key={i}>{self.renderElement2(page)}</div>
);
})}
</div>
</div>
);
}
});
这是应用程序的呈现方式
var data = [1,2,3];
var data2 = [1,2,3];
React.render(<App data={data} data2={data2}/>, document.getElementById("main"));
这是DEMO
My test case:
I add 55 and expect the results to look like this
55
1
2
3
55
1
2
3
But I get
1
2
3
3
55
1
2
3
我是不是漏掉了一些基本的东西?
抱歉,我不知道发生这种情况的确切原因,但如果您在输入中包含键属性的值,问题就会解决:
renderElement: function(i){
return(
<input key={i} defaultValue={i} />
);
},
我的猜测是缺少 'key' 和使用 'defaultValue' 而不是 'value',这使得 React 很难正确区分变化。
第一次渲染看起来(大致)像这样:
<div>
<div key={0}><input defaultValue="1" /></div>
<div key={1}><input defaultValue="2" /></div>
<div key={2}><input defaultValue="3" /></div>
</div>
<div>
<div key={0}><span>1</span></div>
<div key={1}><span>2</span></div>
<div key={2}><span>3</span></div>
</div>
很好,没问题。然后假设我将 'foo' 放入框中并单击添加值。通过在第一个项目之前插入它来更新状态(旁注:splice(0,0,x) is unshift(x)),然后渲染这个:
<div>
<div key={0}><input defaultValue="foo" /></div>
<div key={1}><input defaultValue="1" /></div>
<div key={2}><input defaultValue="2" /></div>
<div key={3}><input defaultValue="3" /></div>
</div>
<div>
<div key={0}><span>foo</span></div>
<div key={1}><span>1</span></div>
<div key={2}><span>2</span></div>
<div key={3}><span>3</span></div>
</div>
现在是 React 处理这两个问题并弄清楚发生了什么变化的时候了。为此,它会比较组件(div、跨度或此处输入)和键。
从 span 部分开始,它看到所有标签都是相同的,但是在 end 处有一个它以前从未见过的新键。它还看到 div[0] span
、div[1] span
和 div[2] span
的值都已更改。它在末尾插入带有文本 3 的 new 元素,并更新其他跨度。效率低下,但有效。
现在输入...它做大致相同的事情。前三个输入的键和标签是相同的,它告诉每个输入他们正在更新,他们检查他们是否有 value prop,如果没有,请拒绝做任何事情。
它看到最后有一个 new 输入。它位于 div[3] input
,默认值为“3”。 React 插入新输入,将值设置为 3,更新完成。
继续,上面的过程是一样的,它继续更新跨度,每次插入一个新的 div span
和 div input
。
这里的主要问题是,除了我认为不应该使用的 defaultValue 之外,键是颠倒的!项目在开头插入,因此键应该下降,而不是上升。这可以通过使用项目的长度并从中减去索引来解决。如果长度为 4,则键将为 4、3、2、1。
this.state.app.data.map(function(page, i, items){
return(
<div key={items.length - i}>{self.renderElement(page)}</div>
);
})
React 然后说'哦,开头有一个新项目,我应该在那里插入一个节点',每个人都很高兴。结束。
我制作了一个简单的应用程序(在 React js 中),它有两个列表,您可以向该列表添加元素。一个是输入元素列表,另一个是跨度列表。
添加新元素后,span 列表呈现完美,但 input 列表呈现不同。
这就是我的反应 class 的样子
var App = React.createClass({
getInitialState: function(){
return {
'app': {
'data': this.props.data,
'data2': this.props.data2
}
};
},
onclick: function(){
var dat = this.state.app.data;
var val = this.refs.input.getDOMNode().value;
dat.splice(0, 0, val);
var dat2 = this.state.app.data2;
dat2.splice(0, 0, val);
this.setState({'app': {
'data': dat,
'data2': dat2
}});
},
renderElement: function(i){
return(
<input defaultValue={i} />
);
},
renderElement2: function(i){
return(
<span>{i}</span>
);
},
render: function(){
var self = this;
return(
<div>
<input type="text" ref="input" placeholder="Enter a value"/>
<input type="button" value="Add value" onClick={this.onclick} />
<div className="col2">
{this.state.app.data.map(function(page, i){
return(
<div key={i}>{self.renderElement(page)}</div>
);
})}
</div>
<div className="col2">
{this.state.app.data2.map(function(page, i){
return(
<div key={i}>{self.renderElement2(page)}</div>
);
})}
</div>
</div>
);
}
});
这是应用程序的呈现方式
var data = [1,2,3];
var data2 = [1,2,3];
React.render(<App data={data} data2={data2}/>, document.getElementById("main"));
这是DEMO
My test case:
I add 55 and expect the results to look like this
55
1
2
3
55
1
2
3
But I get
1
2
3
3
55
1
2
3
我是不是漏掉了一些基本的东西?
抱歉,我不知道发生这种情况的确切原因,但如果您在输入中包含键属性的值,问题就会解决:
renderElement: function(i){
return(
<input key={i} defaultValue={i} />
);
},
我的猜测是缺少 'key' 和使用 'defaultValue' 而不是 'value',这使得 React 很难正确区分变化。
第一次渲染看起来(大致)像这样:
<div>
<div key={0}><input defaultValue="1" /></div>
<div key={1}><input defaultValue="2" /></div>
<div key={2}><input defaultValue="3" /></div>
</div>
<div>
<div key={0}><span>1</span></div>
<div key={1}><span>2</span></div>
<div key={2}><span>3</span></div>
</div>
很好,没问题。然后假设我将 'foo' 放入框中并单击添加值。通过在第一个项目之前插入它来更新状态(旁注:splice(0,0,x) is unshift(x)),然后渲染这个:
<div>
<div key={0}><input defaultValue="foo" /></div>
<div key={1}><input defaultValue="1" /></div>
<div key={2}><input defaultValue="2" /></div>
<div key={3}><input defaultValue="3" /></div>
</div>
<div>
<div key={0}><span>foo</span></div>
<div key={1}><span>1</span></div>
<div key={2}><span>2</span></div>
<div key={3}><span>3</span></div>
</div>
现在是 React 处理这两个问题并弄清楚发生了什么变化的时候了。为此,它会比较组件(div、跨度或此处输入)和键。
从 span 部分开始,它看到所有标签都是相同的,但是在 end 处有一个它以前从未见过的新键。它还看到 div[0] span
、div[1] span
和 div[2] span
的值都已更改。它在末尾插入带有文本 3 的 new 元素,并更新其他跨度。效率低下,但有效。
现在输入...它做大致相同的事情。前三个输入的键和标签是相同的,它告诉每个输入他们正在更新,他们检查他们是否有 value prop,如果没有,请拒绝做任何事情。
它看到最后有一个 new 输入。它位于 div[3] input
,默认值为“3”。 React 插入新输入,将值设置为 3,更新完成。
继续,上面的过程是一样的,它继续更新跨度,每次插入一个新的 div span
和 div input
。
这里的主要问题是,除了我认为不应该使用的 defaultValue 之外,键是颠倒的!项目在开头插入,因此键应该下降,而不是上升。这可以通过使用项目的长度并从中减去索引来解决。如果长度为 4,则键将为 4、3、2、1。
this.state.app.data.map(function(page, i, items){
return(
<div key={items.length - i}>{self.renderElement(page)}</div>
);
})
React 然后说'哦,开头有一个新项目,我应该在那里插入一个节点',每个人都很高兴。结束。