React.js table:删除行按钮在视觉上删除不正确的行
React.js table: remove row button visually removes incorrect row
我正在使用 React.js 动态创建包含文本框的 html table。我有可以通过单击按钮删除的行。我预计,当我在第一行上单击 "remove" 时,table 会重新呈现并删除第 1 行。但是,当 React 重新绘制 table 时,它看起来总是从 DOM 中删除 table 的最后一行,而不是使用我的 state
中的实际值目的。也许我发现了一个错误?这是我的代码:
/** @jsx React.DOM */
var MyApp = React.createClass({
getInitialState: function () {
return {
col_one: ['c1r1', 'c1r2', 'c1r3'],
col_two: ['c2r1', 'c1r2', 'c1r3'],
col_three: ['c3r1', 'c3r2', 'c3r3']
}
},
handleCellChange: function (colName, index, e) {
console.log('onChange:', colName, index, e.target.value);
},
handleRemove: function (i) {
var that = this;
console.log('removing row:',i);
_.forEach(this.state, function (val, colName) {
that.state[colName].splice(i,1); // BUG???
//_.pullAt(that.state[key], i); // doesn't work either
});
console.log(this.state);
this.setState(this.state);
},
render: function() {
var that = this,
rows = [],
cols = _.keys(this.state);
rows.push(
<tr>
{cols.map(function (col) {
return (
<th>{col}</th>
)
})}
</tr>
)
for (var i = 0; i < this.state[cols[0]].length; i++) {
rows.push(
<tr>
{cols.map(function (col) {
return (
<td>
<input type="text" defaultValue={that.state[col][i]} onChange={that.handleCellChange.bind(that, col, i)} />
</td>
)
})}
<td>
<button onClick={this.handleRemove.bind(this, i)}>Remove</button>
</td>
</tr>
)
}
return (
<table>
<tbody>
{rows}
</tbody>
</table>
);
}
});
React.renderComponent(<MyApp />, document.body);
您正在使用 defaultValue
- 这使得输入成为 uncontrolled component,它获得了一个初始值集,但 React 永远不会再触及其显示值,除非您将整个组件炸掉(例如,对其或祖先进行 key
更改)并且它必须从头开始重新创建它。
这就是为什么你看不到新的 defaultValue
被显示的原因 - 因为每一行上没有唯一键,React 发现重新渲染时少了一行,并从真实中删除了最后一行DOM,但保留行中输入的任何新 defaultValue
均无效..
这是相同的代码,但使用了 value
,这使它成为 controlled component,反映了重新渲染时获得的新 value
:
我正在使用 React.js 动态创建包含文本框的 html table。我有可以通过单击按钮删除的行。我预计,当我在第一行上单击 "remove" 时,table 会重新呈现并删除第 1 行。但是,当 React 重新绘制 table 时,它看起来总是从 DOM 中删除 table 的最后一行,而不是使用我的 state
中的实际值目的。也许我发现了一个错误?这是我的代码:
/** @jsx React.DOM */
var MyApp = React.createClass({
getInitialState: function () {
return {
col_one: ['c1r1', 'c1r2', 'c1r3'],
col_two: ['c2r1', 'c1r2', 'c1r3'],
col_three: ['c3r1', 'c3r2', 'c3r3']
}
},
handleCellChange: function (colName, index, e) {
console.log('onChange:', colName, index, e.target.value);
},
handleRemove: function (i) {
var that = this;
console.log('removing row:',i);
_.forEach(this.state, function (val, colName) {
that.state[colName].splice(i,1); // BUG???
//_.pullAt(that.state[key], i); // doesn't work either
});
console.log(this.state);
this.setState(this.state);
},
render: function() {
var that = this,
rows = [],
cols = _.keys(this.state);
rows.push(
<tr>
{cols.map(function (col) {
return (
<th>{col}</th>
)
})}
</tr>
)
for (var i = 0; i < this.state[cols[0]].length; i++) {
rows.push(
<tr>
{cols.map(function (col) {
return (
<td>
<input type="text" defaultValue={that.state[col][i]} onChange={that.handleCellChange.bind(that, col, i)} />
</td>
)
})}
<td>
<button onClick={this.handleRemove.bind(this, i)}>Remove</button>
</td>
</tr>
)
}
return (
<table>
<tbody>
{rows}
</tbody>
</table>
);
}
});
React.renderComponent(<MyApp />, document.body);
您正在使用 defaultValue
- 这使得输入成为 uncontrolled component,它获得了一个初始值集,但 React 永远不会再触及其显示值,除非您将整个组件炸掉(例如,对其或祖先进行 key
更改)并且它必须从头开始重新创建它。
这就是为什么你看不到新的 defaultValue
被显示的原因 - 因为每一行上没有唯一键,React 发现重新渲染时少了一行,并从真实中删除了最后一行DOM,但保留行中输入的任何新 defaultValue
均无效..
这是相同的代码,但使用了 value
,这使它成为 controlled component,反映了重新渲染时获得的新 value
: