React表单多字段存入数组问题:无法存储Last Name与Phone字段
解决React表单无法存储多字段与表格渲染问题
嘿,我发现你的代码里有几个关键问题导致了First Name之外的字段无法正确存储和渲染,咱们一个个来修复:
1. 字段名称不匹配
在Contacts.js的addItem方法中,你把Phone输入框的值存在了phonename属性里,但在ContactList.js渲染表格的时候,你尝试读取的是item.phone——这两个名字对不上,所以Phone列自然拿不到数据。
2. JSX语法与表格结构错误
在ContactList.js的createContact函数里:
- 第一个
<td>后面多了个逗号,这会导致JSX解析出错,影响后续元素渲染 - 你把所有生成的
<tr>都包裹在了一个额外的<tr>里,这完全破坏了表格的结构,浏览器无法正确解析多行数据
3. (可选)异步状态更新的调试问题
setState是异步操作,所以你在addItem里直接console.log(this.state.items)大概率看不到刚添加的最新数据,如果要调试的话,可以用setState的回调函数:
this.setState((prevState) => { return { items: prevState.items.concat(newItem) }; }, () => { console.log(this.state.items); // 这里能拿到最新状态 });
修正后的Contacts.js
import ContactList from "./ContactList"; class Contacts extends Component { constructor(props) { super(props); this.state = { items: [] }; this.addItem = this.addItem.bind(this); this.deleteItem = this.deleteItem.bind(this); } addItem(e) { if(this._inputElement.value !== "") { var newItem = { firstname: this._inputElement.value, lastname: this._inputElement2.value, phone: this._inputElement3.value, // 这里把phonename改成phone,和渲染时的字段名统一 key: Date.now() }; this.setState((prevState) => { return { items: prevState.items.concat(newItem) }; }, () => { console.log(this.state.items); // 用回调查看最新状态 }); this._inputElement.value = ""; this._inputElement2.value = ""; this._inputElement3.value = ""; } e.preventDefault(); } deleteItem(key) { var filteredItems = this.state.items.filter(function (item) { return (item.key !== key); }); this.setState({ items: filteredItems }); } render () { return ( <Panel> <Tabs onChange={this.onChange} defaultSelectedIndex={0} justified={true}> <Tab value="pane-1" label="Add Contact" onActive={this.onActive}> <Form onSubmit={this.addItem}> <input ref={(a) => this._inputElement = a} placeholder="First Name" /> <input ref={(a) => this._inputElement2 = a} placeholder="Last Name" /> <input ref={(a) => this._inputElement3 = a} placeholder="Phone" /> <Button variant="raised">Add</Button> </Form> </Tab> <Tab value="pane-2" label="List Contacts"> <ContactList entries={this.state.items} delete={this.deleteItem}/> </Tab> </Tabs> </Panel> ); } } export default Contacts
修正后的ContactList.js
class ContactList extends Component { constructor(props) { super(props); this.createContact = this.createContact.bind(this); } delete(key) { this.props.delete(key); } createContact(item) { return <tr key={item.key}> <td onClick={() => this.delete(item.key)}>{item.firstname}</td> {/* 去掉多余的逗号 */} <td>{item.lastname}</td> <td>{item.phone}</td> {/* 现在字段名匹配了 */} </tr> } render() { var contactEntries = this.props.entries; var listItems = contactEntries.map(this.createContact); return ( <table className="mui-table"> <thead> <tr> <th>First Name</th> <th>Last Name</th> <th>Phone</th> </tr> </thead> <tbody> {listItems} {/* 直接放生成的tr,不要包裹额外的tr */} </tbody> </table> ); } }; export default ContactList;
这样修改之后,表单就能正确存储三个字段的值,表格也能正常渲染每一行的三列内容了。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

