我正在尝试制作一个表,其中可以在表中添加条目或从表中删除条目,反之亦然。
似乎错误发生在setState方法中,因为未执行回调中的日志。
这是我的组件:
Array.prototype.invertedSplice = function() {
Array.prototype.splice.apply(this, arguments);
return this;
};
class SomeName extends React.Component {
constructor(props) {
super(props);
this.state = {
table: {
country: ["United States", "Canada", "Great Britain"],
medals: [127, 63, 67]
},
dropdown: {
country: [],
medals: []
}
};
this.TableView = this.TableView.bind(this);
this.ListView = this.ListView.bind(this);
}
ListView() {
let list = [];
for (let i = 0; i < this.state.dropdown.country.length; i++) {
list.push(<div class="listitem">
{this.state.dropdown.country[i]}
<button key={this.state.dropdown.country[i]} onClick={this.addEntry.bind(this, i)}><svg/></button>
</div>);
}
return(list);
}
TableView() {
let table = [];
console.log("tableview called");
for (let i = 0; i < this.state.table.country.length; i++) {
table.push(
<tr>
<td>{this.state.table.country[i]}</td>
<td>{this.state.table.medals[i]}</td>
<td key={this.state.table.country[i]}><button onClick={this.removeEntry.bind(this, i)}><svg width="70" height="5">
<line x1="3" y1="2.5" x2="67" y2="2.5" />
</svg></button></td>
</tr>
);
}
return(table);
}
addEntry (entryIndex) {
this.setState((prevState) => ({
table: {
country:
this.state.table.country.splice(entryIndex, 0, this.state.dropdown.country[entryIndex]),
medals: this.state.table.medals.splice(entryIndex, 0, this.state.dropdown.medals[entryIndex])
},
dropdown: {
country: this.state.dropdown.country.invertedSplice(this.state.dropdown.country[entryIndex], 1),
medals: this.state.dropdown.medals.invertedSplice(this.state.dropdown.medals[entryIndex], 1)
}
}));
}
removeEntry (entryIndex) {
console.log("removeEntry called")
this.setState((prevState) => ({
table: {
country: this.state.table.country.invertedSplice(this.state.table.country[entryIndex], 1),
medals: this.state.table.medals.invertedSplice(this.state.table.medals[entryIndex], 1)
},
dropdown: {
country:
this.state.dropdown.country.concat(this.state.table.country.splice(entryIndex, 1)),
medals: this.state.dropdown.medals.concat(this.state.dropdown.medals.splice(entryIndex, 1))
}
}), () => console.log("the state was set"));
}
render() {
console.log("render called");
return(
<div>
<div className="list">
<this.ListView />
</div>
<div className="table">
<table>
<caption>Example!</caption>
<tbody>
<tr>
<th>Country</th>
<th>Medals</th>
</tr>
<this.TableView />
</tbody>
</table>
</div>
</div>
);
}
}
这是我的第一个问题,请随时给我有关礼节或代码质量的任何提示。
最佳答案
如果尝试使用https://stackoverflow.com/a/55211138/2763250中的spliced
函数,则将其移出组件,因为您只是向Array
原型添加了一个函数。 country
是一个数组,并且spliced()
在Array原型上不存在,因此引发了错误。您的组件中只有一个spliced()
函数。
Array.prototype.spliced = function() {
Array.prototype.splice.apply(this, arguments);
return this;
};
class SomeName extends React.Component {
constructor(props) {
super(props);
this.state = {
table: {
country: ["United States", "Canada", "Great Britain"],
medals: [127, 63, 67]
},
dropdown: {
country: [],
medals: []
}
};
this.TableView = this.TableView.bind(this);
this.ListView = this.ListView.bind(this);
}
ListView() {
let list = [];
for (let i = 0; i < this.state.dropdown.country.length; i++) {
list.push(
<div class="listitem">
{this.state.dropdown.country[i]}
<button
key={this.state.dropdown.country[i]}
onClick={this.addEntry.bind(this, i)}
>
<svg />
</button>
</div>
);
}
return list;
}
TableView() {
let table = [];
console.log("tableview called");
for (let i = 0; i < this.state.table.country.length; i++) {
table.push(
<tr>
<td>{this.state.table.country[i]}</td>
<td>{this.state.table.medals[i]}</td>
<td key={this.state.table.country[i]}>
<button onClick={this.removeEntry.bind(this, i)}>
<svg width="70" height="5">
<line x1="3" y1="2.5" x2="67" y2="2.5" />
</svg>
</button>
</td>
</tr>
);
}
return table;
}
addEntry(entryIndex) {
this.setState(prevState => ({
table: {
country: this.state.table.country.splice(
entryIndex,
0,
this.state.dropdown.country[entryIndex]
),
medals: this.state.table.medals.splice(
entryIndex,
0,
this.state.dropdown.medals[entryIndex]
)
},
dropdown: {
country: this.state.dropdown.country.spliced(
this.state.dropdown.country[entryIndex],
1
),
medals: this.state.dropdown.medals.spliced(
this.state.dropdown.medals[entryIndex],
1
)
}
}));
}
removeEntry(entryIndex) {
console.log("removeEntry called");
this.setState(
prevState => ({
table: {
country: this.state.table.country.spliced(
this.state.table.country[entryIndex],
1
),
medals: this.state.table.medals.spliced(
this.state.table.medals[entryIndex],
1
)
},
dropdown: {
country: this.state.dropdown.country.concat(
this.state.table.country.splice(entryIndex, 1)
),
medals: this.state.dropdown.medals.concat(
this.state.dropdown.medals.splice(entryIndex, 1)
)
}
}),
() => console.log("the state was set")
);
}
render() {
console.log("render called");
return (
<div>
<div className="list">
<this.ListView />
</div>
<div className="table">
<table>
<caption>Example!</caption>
<tbody>
<tr>
<th>Country</th>
<th>Medals</th>
</tr>
<this.TableView />
</tbody>
</table>
</div>
</div>
);
}
}
ReactDOM.render(<SomeName />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>