ReactJS多输入表单转动态表
我正在尝试制作一个小型 D&D 计划跟踪器。我正在尝试修改表单以获取多个输入并生成动态表。
我当前的问题是,当我提交表单时,会创建一个 4x4 表格,其中每个输入显示在一行的每一列上,而不是一行每列一个输入。我对道具仍然有点模糊,所以我不确定这是否是我脱节的地方或其他地方。
代码基于 这个。
这是DynamicTable.jsx;
import React from 'react';
export default class DynamicTable extends React.Component {
constructor(props) {
super(props);
this.state = {
initiative: "",
name: "",
armorClass: "",
hitPoints: "",
combatants: []
}
}
updateInitiative(event) {
this.setState({initiative: event.target.value});
}
updateName(event) {
this.setState({name: event.target.value});
}
updateArmorClass(event) {
this.setState({armorClass: event.target.value});
}
updateHitPoints(event) {
this.setState({hitPoints: event.target.value});
}
handleClick() {
var combatants = this.state.combatants;
combatants.push(this.state.initiative);
combatants.push(this.state.name);
combatants.push(this.state.armorClass);
combatants.push(this.state.hitPoints);
this.setState({
combatants: combatants,
initiative: "",
name: "",
armorClass: "",
hitPoints: ""
});
}
handleCombatantChanged(i, event) {
var combatants = this.state.combatants;
combatants[i] = event.target.value;
this.setState({
combatants: combatants
});
}
handleCombatantDeleted(i) {
var combatants = this.state.combatants;
combatants.splice(i, 1);
this.setState({
combatants: combatants
});
}
renderRows() {
var context = this;
return this.state.combatants.map(function(o, i) {
return (
<tr key={"combatant-" + i}>
<td>
<input
id="initiative"
type="text"
value={o}
onChange={context.handleCombatantChanged.bind(context, i)}
/>
</td>
<td>
<input
id="name"
type="text"
value={o}
onChange={context.handleCombatantChanged.bind(context, i)}
/>
</td>
<td>
<input
id="armorClass"
type="text"
value={o}
onChange={context.handleCombatantChanged.bind(context, i)}
/>
</td>
<td>
<input
id="hitPoints"
type="text"
value={o}
onChange={context.handleCombatantChanged.bind(context, i)}
/>
</td>
<td>
<button onClick={context.handleCombatantDeleted.bind(context, i)}>
Finish him!
</button>
</td>
</tr>
);
});
}
render() {
return (
<div>
<table>
<td>
<th>Initiative</th>
<input
id="initiative"
type="text"
value={this.state.initiative}
onChange={this.updateInitiative.bind(this)}
/>
</td>
<td>
<th>Name</th>
<input
id="name"
type="text"
value={this.state.name}
onChange={this.updateName.bind(this)}
/>
</td>
<td>
<th>Armor Class</th>
<input
id="armorClass"
type="text"
value={this.state.armorClass}
onChange={this.updateArmorClass.bind(this)}
/>
</td>
<td>
<th>Hit Points</th>
<input
id="hitPoints"
type="text"
value={this.state.hitPoints}
onChange={this.updateHitPoints.bind(this)}
/>
</td>
<td><th></th>
<button onClick={this.handleClick.bind(this)}>
Add Combatant
</button>
</td>
</table>
<table className="">
<thead>
<tr>
<th>Initiative</th>
<th>Name</th>
<th>Armor Class</th>
<th>Hit Points</th>
<th>Kill?</th>
</tr>
</thead>
<tbody>
{this.renderRows()}
</tbody>
</table>
</div>
);
}
}
这是App.js;
import DynamicTable from './DynamicTable';
function App() {
return (
<div className="App">
<DynamicTable />
</div>
);
}
export default App;
I'm trying to make a little D&D initiative tracker. I'm trying to modify a form to take multiple inputs and generate a dynamic table.
My current issue is that when I submit the form, a 4x4 table is created with each input displaying across each column of a row instead of one row with one input per column. I'm still a little fuzzy on props so I'm not sure if that's where my disconnect is or somewhere else.
Code is based on this.
This is DynamicTable.jsx;
import React from 'react';
export default class DynamicTable extends React.Component {
constructor(props) {
super(props);
this.state = {
initiative: "",
name: "",
armorClass: "",
hitPoints: "",
combatants: []
}
}
updateInitiative(event) {
this.setState({initiative: event.target.value});
}
updateName(event) {
this.setState({name: event.target.value});
}
updateArmorClass(event) {
this.setState({armorClass: event.target.value});
}
updateHitPoints(event) {
this.setState({hitPoints: event.target.value});
}
handleClick() {
var combatants = this.state.combatants;
combatants.push(this.state.initiative);
combatants.push(this.state.name);
combatants.push(this.state.armorClass);
combatants.push(this.state.hitPoints);
this.setState({
combatants: combatants,
initiative: "",
name: "",
armorClass: "",
hitPoints: ""
});
}
handleCombatantChanged(i, event) {
var combatants = this.state.combatants;
combatants[i] = event.target.value;
this.setState({
combatants: combatants
});
}
handleCombatantDeleted(i) {
var combatants = this.state.combatants;
combatants.splice(i, 1);
this.setState({
combatants: combatants
});
}
renderRows() {
var context = this;
return this.state.combatants.map(function(o, i) {
return (
<tr key={"combatant-" + i}>
<td>
<input
id="initiative"
type="text"
value={o}
onChange={context.handleCombatantChanged.bind(context, i)}
/>
</td>
<td>
<input
id="name"
type="text"
value={o}
onChange={context.handleCombatantChanged.bind(context, i)}
/>
</td>
<td>
<input
id="armorClass"
type="text"
value={o}
onChange={context.handleCombatantChanged.bind(context, i)}
/>
</td>
<td>
<input
id="hitPoints"
type="text"
value={o}
onChange={context.handleCombatantChanged.bind(context, i)}
/>
</td>
<td>
<button onClick={context.handleCombatantDeleted.bind(context, i)}>
Finish him!
</button>
</td>
</tr>
);
});
}
render() {
return (
<div>
<table>
<td>
<th>Initiative</th>
<input
id="initiative"
type="text"
value={this.state.initiative}
onChange={this.updateInitiative.bind(this)}
/>
</td>
<td>
<th>Name</th>
<input
id="name"
type="text"
value={this.state.name}
onChange={this.updateName.bind(this)}
/>
</td>
<td>
<th>Armor Class</th>
<input
id="armorClass"
type="text"
value={this.state.armorClass}
onChange={this.updateArmorClass.bind(this)}
/>
</td>
<td>
<th>Hit Points</th>
<input
id="hitPoints"
type="text"
value={this.state.hitPoints}
onChange={this.updateHitPoints.bind(this)}
/>
</td>
<td><th></th>
<button onClick={this.handleClick.bind(this)}>
Add Combatant
</button>
</td>
</table>
<table className="">
<thead>
<tr>
<th>Initiative</th>
<th>Name</th>
<th>Armor Class</th>
<th>Hit Points</th>
<th>Kill?</th>
</tr>
</thead>
<tbody>
{this.renderRows()}
</tbody>
</table>
</div>
);
}
}
This is App.js;
import DynamicTable from './DynamicTable';
function App() {
return (
<div className="App">
<DynamicTable />
</div>
);
}
export default App;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
与您提供的链接的不同之处在于,您想要显示的不仅仅是一条消息,而是一个战斗人员。这完全没问题。我认为您希望您的战斗人员数组成为一个对象数组,如下所示:
而不是这样:
您会得到 4 行,因为您附加了战斗人员数组 4 次。只需附加一次,但附加一个包含一名战斗人员所有信息的对象:
但需要进行额外的更改。现在,您的战斗人员数组不再是字符串数组,而是对象数组,您必须更改
renderRows
输入中显示的值。您的所有值都显示相同的东西o
,它是一个字符串。现在,o
将是一个对象,您需要访问战斗对象的值,例如:The difference with the link you provided is that instead of just a message, you want to display a combatant. Which is totally fine. I think you want your combatants array to be an array of objects, like this:
Instead of this :
You get 4 rows because you append your combatants array 4 times. Just append it once but with an object which contains all information for one combatant :
But an additional change is needed. Now, your array of combatants is no longer an array of strings but an array of objects you will have to change the value displayed in your inputs of the
renderRows
. All your values display the same thingo
which was a string. Now,o
will be an object and you need to access values of your combatant object, for example :