reactjs - react js : Input element renders differently compared to other elements

标签 reactjs

我制作了一个简单的应用程序(在 React js 中),它有两个列表,您可以向该列表添加元素。一个是输入元素列表,另一个是跨度列表。

添加新元素后,跨度列表呈现完美,但输入列表呈现不同。

这就是我的 react 类的样子

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

我在这里缺少一些基本的东西吗?

最佳答案

第一次渲染看起来(大致)像这样:

<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) 是 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 或此处的输入)和键。

从span部分开始,它看到所有标签都是相同的,但是在末尾有一个以前没有见过的新键。它还发现 div[0] spandiv[1] spandiv[2] span 的值都已更改。它插入末尾带有文本 3 的 new 元素,并更新其他跨度。效率低下,但有效。

现在对于输入...它的作用大致相同。前三个输入的键和标签是相同的,它告诉每个输入它们正在更新,它们检查它们是否有 value 属性,如果没有,请拒绝执行任何操作。

它看到末尾有一个输入。它位于 div[3] input 处,默认值为“3”。 React 插入新的输入,将值设置为 3,更新完成。

当您继续时,上述过程是相同的,并且它会继续更新范围,并每次插入新的 div spandiv input

这里的主要问题,除了我认为不应该使用的 defaultValue 之外,是按键颠倒了!项目是在开头插入的,因此键应该下降,而不是上升。这可以通过使用项目的长度并从中减去索引来解决。如果长度为 4,则 key 将为 4, 3, 2, 1。

this.state.app.data.map(function(page, i, items){
  return(
    <div key={items.length - i}>{self.renderElement(page)}</div>
  );
})

React 然后说“哦,开头有一个新项目,我应该在那里插入一个节点”,然后每个人都很高兴。结束。

关于reactjs - react js : Input element renders differently compared to other elements,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28258517/

相关文章:

javascript - 如何在 Reactjs 中监听 firebase 实时变化?

reactjs - NextJS中的摇晃树包括所有的node_modules包,即使没有全部使用它

javascript - 如何遍历数据集合并返回整个对象?

javascript - React Router,超出最大调用堆栈大小

javascript - 异常管理器.js :84 Unhandled JS Exception: ReferenceError: response is not defined

android - 是否可以从 React App 访问 NFC 功能

javascript - react 福米克 : how to use custom onChange and onBlur

javascript - 如何单击按钮以获取具有反应的组件之一

reactjs - 错误: Failed to load bundle localhost:8081

reactjs - Div 不会从 css-grid parent 推断最大宽度,省略号永远不会发生