在React Form无状态组件和状态完全Root组件之间传递多个输入字段
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在React Form无状态组件和状态完全Root组件之间传递多个输入字段相关的知识,希望对你有一定的参考价值。
我是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;
答案
将表单元素移动到其自己的专用组件中是一种很好的方法。但是不要尝试从父组件处理子组件的表单提交事件。子组件拥有该组件,它应该处理其突变和提交。考虑到这一点,这就是我构建组件的方式:
- 你的
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>
);
}
}
以上是关于在React Form无状态组件和状态完全Root组件之间传递多个输入字段的主要内容,如果未能解决你的问题,请参考以下文章
[react] 描述下在react中无状态组件和有状态组件的区别是什么?