我是React的初学者,我试图制作一个地址簿应用程序(目前仅限前端)。我在App.js文件中有一个名为App的根组件,我试图将表单元素从根组件移动到AddContact.js文件中的自己的组件(无状态)。当表单是表单提交处理函数的根组件的一部分时,我能够找到一种方法(搜索SO)来传递表单输入字段。但是当表单元素是不同组件的一部分时,我无法做同样的事情。下面是App.js和AddContact.js文件。我该怎么办呢?最好以最简单的方式,同时遵守react / es6最佳实践。
App.js
import React, { Component } from 'react';
import './App.css';
//import AddContact from './AddContact/AddContact';
//import './AddContact/AddContact.css';
import ContactList from './ContactList/ContactList.js';
import Cockpit from './Cockpit/Cockpit.js';
class App extends Component {
state = {
contacts:[]
};
addContactHandler = (event) => {
event.preventDefault();
//console.log(event.target[0].value);
//console.log(event.target.name.value);
const name = this.input1.value;
const phone = this.input2.value;
const email = this.input3.value;
let contacts = [...this.state.contacts];
if (name.length>0 && phone.length>0 && email.length>0){
let contact = {
name: name,
phone: phone,
email: email
};
contacts.push(contact);
console.log("contacts: ", contacts);
this.setState({
contacts:contacts
});
}
this.input1.value = '';
this.input2.value = '';
this.input3.value = '';
};
render() {
let contactList = null;
let contacts = [...this.state.contacts];
if (contacts.length > 0) {
contactList = (
<ContactList
contacts = {contacts}
/>
);
}
return (
<div className="App">
<Cockpit/>
<p>Add New Contact:</p>
<form className="AddContact" onSubmit={(event)=>this.addContactHandler(event)}>
<label>Name:
<input type="text" name="name" ref={(name) => {this.input1 = name}}/>
</label>
<label>Phone:
<input type="text" name="phone" ref={(phone) => {this.input2 = phone}}/>
</label>
<label>Email:
<input type="text" name="email" ref={(email) => {this.input3 = email}}/>
</label>
<input type="submit" value="Submit" />
</form>
{/* <AddContact submit={(event)=>this.addContactHandler(event)}/> */}
{contactList}
</div>
);
}
}
export default App;
AddContact.js
// Use at a later stage
import React from 'react';
import './AddContact.css';
const AddContact = (props) => {
return (
<div >
<p>Add New Contact:</p>
<form className="AddContact" onSubmit={props.submit}>
<label>Name:
<input type="text" ref={(name) => {this.input = name}}/>
</label>
<label>Phone:
<input type="text" ref={(phone) => {this.input2 = phone}}/>
</label>
<label>Email:
<input type="text" ref={(email) => {this.input3 = email}}/>
</label>
<input type="submit" value="Submit" />
</form>
</div>
);
};
export default AddContact;
答案 0 :(得分:1)
将表单元素移动到自己的专用组件中是一种很好的方法。但是,请勿尝试从父组件处理子组件的表单提交事件。子组件拥有该组件,它应该处理其突变和提交。考虑到这一点,这就是我构建组件的方式:
您的App
呈现AddContact
组件。
对于您的AddContact
组件,请勿向其传递onSubmit
处理程序。相反,传递一个onAdd
处理程序,该处理程序期望contact
对象作为其参数。
让您的AddContact
组件有状态!您是否有任何特殊原因希望它成为无国籍人?使其成为有状态,让它处理表单更新作为其状态的一部分(使用Controlled Components)。最后,在表单onSubmit
事件中,打包一个contact
对象并使用它调用props.onAdd
处理程序。
这将是一个更清洁,更合理分离的组件架构。父组件不应该担心子组件的表单提交行为,而应该期待一个包装良好的contact
对象。
检查出来:https://mn627xy99.codesandbox.io/
class AddContact extends React.Component {
state = {
name: "",
phone: "",
email: "",
}
submit = e => {
e.preventDefault();
this.props.onAdd(this.state);
// Clear the form
this.setState({name: "", phone: "", email: ""});
}
change = e => {
e.preventDefault();
this.setState({[e.currentTarget.name]: e.currentTarget.value});
}
render() {
return (
<div >
<p>Add New Contact:</p>
<form className="AddContact" onSubmit={this.submit}>
<label>Name:
<input type="text" name="name" onChange={this.change} value={this.state.name} />
</label>
<label>Phone:
<input type="text" name="phone" onChange={this.change} value={this.state.phone} />
</label>
<label>Email:
<input type="text" name="email" onChange={this.change} value={this.state.email} />
</label>
<input type="submit" value="Submit" />
</form>
</div>
);
}
}