gpt4 book ai didi

javascript - 更改表结构会导致 React 失去对 DOM 的跟踪

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:33:55 25 4
gpt4 key购买 nike

我正在尝试在 React 中创建一个表组件,其中的列和行都是动态的并且会随时间变化。但是,当数据发生变化时,React 会抛出意外的 DOM 突变不变性违规。

这是一个演示问题的 fiddle http://jsfiddle.net/69z2wepo/1797/ .如您所见,初始渲染后数据发生变化,React 无法再跟踪 DOM 的状态。

代码在这里:

var Table = React.createClass({
getDefaultProps: function() {
return {
data: [
{
colA: { value: 'foo' },
},
],
};
},
render: function() {
return (
<table>
<thead>
<tr> {
Object.keys(this.props.data[0]).map(function(key) {
return (<th>{ key }</th>);
}.bind(this))
} </tr>
</thead>
<tbody> {
this.props.data.map(function(item) {
return (<tr> { Object.keys(item).map(function(key) {
return (
<td>{ item[key] }</td>
);
}.bind(this)) } </tr>);
}.bind(this))
} </tbody>
</table>
);
}
});

var Main = React.createClass({
componentWillMount: function() {
setTimeout(function() {
var data = [
{
colA: {
value: 'foobar',
},
},
];
this.setState({
data: data,
});
}.bind(this), 3000);
},
getInitialState: function() {
var data = [
{
colA: {
value: 'foo',
},
colB: {
value: 'bar',
}
},
{
colA: {
value: 'foo',
},
colB: {
value: 'bar',
}
}
];

return {
data: data,
};
},
render: function() {
return (<Table data={ this.state.data } />);
},
});

React.render(<Main />, document.body);
console.log(React.renderToString(<Table/>));

我已经尝试了各种添加关键属性来跟踪各种元素的方法,但似乎没有什么可以解决这个问题。

使用 renderToString 渲染表格组件显示 React 正在表格的不同级别插入一堆元素。这是可能的原因吗?在此处查看正在呈现的 DOM:

<table data-reactid=".1" data-react-checksum="1098817301">
<thead data-reactid=".1.0">
<tr data-reactid=".1.0.0">
<span data-reactid=".1.0.0.0"> </span>
<th data-reactid=".1.0.0.1:0">colA</th>
<span data-reactid=".1.0.0.2"> </span>
</tr>
</thead>
<tbody data-reactid=".1.1">
<span data-reactid=".1.1.0"> </span>
<tr data-reactid=".1.1.1:0">
<span data-reactid=".1.1.1:0.0"> </span>
<td data-reactid=".1.1.1:0.1:0"><span data-reactid=".1.1.1:0.1:0.$value:0">foo</span></td>
<span data-reactid=".1.1.1:0.2"> </span>
</tr>
<span data-reactid=".1.1.2"> </span>
</tbody>
</table>

最佳答案

原来问题出在你的缩进上。如果您在新行上开始花括号 {}(花括号在 JSX 中编写 javascript),您的代码就可以工作。虽然不确定为什么会发生。

jsfiddle:http://jsfiddle.net/cwn2nebs/

var Table = React.createClass({
getDefaultProps: function() {
return {
data: [
{
colA: { value: 'foo' },
},
],
};
},
render: function() {
return (
<table>
<thead>
<tr>
{
Object.keys(this.props.data[0]).map(function(key, idx) {
return (<th key={ idx } >{ key }</th>);
}.bind(this))
}
</tr>
</thead>
<tbody>
{
this.props.data.map(function(item, idx) {
return (
<tr key={ idx }>
{
Object.keys(item).map(function(key, i) {
return (
<td key={ i }>{ item[key] }</td>
);
}.bind(this)) }
</tr>);
}.bind(this))

}
</tbody>
</table>
);
}
});

var Main = React.createClass({
componentWillMount: function() {
setTimeout(function() {
var data = [
{
colA: {
value: 'foobar',
}
},
];
this.setState({
data: data,
});
}.bind(this), 3000);
},
getInitialState: function() {
var data = [
{
colA: {
value: 'foo',
},
colB: {
value: 'bar',
}
},
{
colA: {
value: 'foo',
},
colB: {
value: 'bar',
}
}
];

return {
data: data,
};
},
render: function() {
return (<Table data={ this.state.data } />);
},
});

React.render(<Main />, document.body);

更新

使用 JSX compiler我试图将您的部分代码转换为纯 JS:

 render: function() {
return (
React.createElement("table", null,
React.createElement("thead", null,
React.createElement("tr", null, " ",
Object.keys(this.props.data[0]).map(function(key, idx) {
return (React.createElement("th", {key: idx }, key ));
}.bind(this)),
" ")
),
React.createElement("tbody", null, " ",
this.props.data.map(function(item, idx) {
return (React.createElement("tr", {key: idx }, " ", Object.keys(item).map(function(key, i) {
return (
React.createElement("td", {key: i }, item[key] )
);
}.bind(this)), " "));
}.bind(this)),

" ")
)
);
}

React.createElement 是这样工作的:

React.createElement(type, props, children);

注意 tr 元素的空子元素:

React.createElement("tr", null, " ", 
Object.keys(this.props.data[0]).map(function(key, idx) {
return (React.createElement("th", {key: idx }, key ));
}.bind(this)),
" ")

但是在新行上加上花括号,编译后的代码看起来像这样(没有空的 ("") child ):

React.createElement("tr", null,     
Object.keys(this.props.data[0]).map(function(key, idx) {
return (React.createElement("th", {key: idx }, key ));
}.bind(this))
)

我相信 React 将 "" 子元素转换为 span 元素,正如您所发现的,这是导致问题的原因。

关于javascript - 更改表结构会导致 React 失去对 DOM 的跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28307091/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com