创建对象并将其传递给父组件的最佳做法是什么?我的下面的代码运行良好,但似乎我必须在这里投入太多东西只是为了提交一个包含2个字段的简单表单。
我正在创建构造函数,
听取事件,
绑定事件,
更新并将状态传递给App.js
这是最佳做法吗?:
class AddFishForm extends React.Component {
constructor(props) {
super(props);
this.state = {
title: '',
amount: ''
};
this.onTitleChange = this.onTitleChange.bind(this);
this.onAmountChange = this.onAmountChange.bind(this);
}
onTitleChange = (e) => {
const title = e.target.value;
this.setState(() => ({ title }));
};
onAmountChange = (e) => {
const amount = e.target.value;
this.setState(() => ({ amount }));
};
createFish(event) {
event.preventDefault();
this.props.addFish({
url: this.state.url,
title: this.state.title
});
}
render () {
return (
<Segment>
<Form onSubmit={(e) => this.createFish(e)}>
<Form.Group >
<Form.Input
type='text'
placeholder='picture url'
autoFocus
value={this.state.title}
onChange={this.onTitleChange}
width={6}
/>
<Form.Input
type='text'
placeholder='title'
autoFocus
value={this.state.amount}
onChange={this.onAmountChange}
width={6}
/>
</Form.Group >
<Button fluid type='submit'>Submit</Button>
</Form>
</Segment>
)
}
}
答案 0 :(得分:1)
您可以通过提供更新状态的更通用方法来简化代码:
onInputChange = (e) => {
const target = e.target;
const name = target.name;
const value = target.type === 'checkbox' ? target.checked : target.value;
// add code for other input types
this.setState(() => ({ [name]: value }));
};
在构造函数中绑定此方法
this.onInputChange = this.onInputChange.bind(this);
并在你的元素上使用它
<input
type='text'
name='title'
value={this.state.title}
onChange={this.onInputChange}
...
/>
<input
type='checkbox'
name='is_subsribed'
checked={this.state.is_subsribed}
onChange={this.onInputChange}
...
/>
name属性将输入连接到正确的状态值
答案 1 :(得分:0)
如果您不需要对input
进行进一步操作,请使用uncontrolled components。这是代码的非受控组件版本
class AddFishForm extends React.Component {
constructor(props) {
super(props);
}
createFish(event) {
event.preventDefault();
const url = this._url.value;
const title = this._title.value;
this.props.addFish({ url, title });
}
render () {
return (
<Segment>
<Form onSubmit={(e) => this.createFish(e)}>
<Form.Group >
<input
ref={input => this._url = input}
type='text'
width={6} />
<input
ref={input => this._title = input}
type='text
width={6} />
</Form.Group >
<Button fluid type='submit'>Submit</Button>
</Form>
</Segment>
)
}
}
答案 2 :(得分:0)
最佳实践将从这样的事情开始:
class AddFishForm extends React.Component {
onInputChange() {
}
render() {
return (
<div className="semantic ui segment">
<form className="ui form">
<div className="field">
<label>Image Search</label>
<input type="text" onChange={this.onInputChange} />
</div>
</form>
</div>
);
}
}
export default AddFishForm;
运行onInputChange()
时会自动传递一个参数,通常称为event
对象。该对象包含一堆有关刚刚发生的事件的信息,如下所示:
class AddFishForm extends React.Component {
onInputChange(event) {
}
render() {
return (
<div className="semantic ui segment">
<form className="ui form">
<div className="field">
<label>Image Search</label>
<input type="text" onChange={this.onInputChange} />
</div>
</form>
</div>
);
}
}
export default AddFishForm;
在用户键入内容的情况下,我们关心的整个对象中通常有一个属性,即event.target.value
属性。它将包含用户刚刚尝试在输入中键入的文本,如下所示:
class AddFishForm extends React.Component {
onInputChange(event) {
event.target.value
}
render() {
return (
<div className="semantic ui segment">
<form className="ui form">
<div className="field">
<label>Image Search</label>
<input type="text" onChange={this.onInputChange} />
</div>
</form>
</div>
);
}
}
export default AddFishForm;
您可以通过控制台注销并查看您的状态来进行测试:
class AddFishForm extends React.Component {
onInputChange(event) {
console.log(event.target.value);
}
render() {
return (
<div className="semantic ui segment">
<form className="ui form">
<div className="field">
<label>Image Search</label>
<input type="text" onChange={this.onInputChange} />
</div>
</form>
</div>
);
}
}
export default AddFishForm;
添加文本时,应该将其调出,这应该是预期的行为。
onChange
是一个非常特殊的属性名称。不同的事件将被关联到不同的属性名称。因此,在这种情况下,您似乎希望在用户更改文本输入的任何时间都被告知,因此我假设这就是您使用属性名称onChange
的原因。
对于事件处理程序,您在命名约定中使用社区约定,因此您在这里很好。
所以这就是事件处理的总括。还有写出事件处理程序的另一种语法。
class AddFishForm extends React.Component {
onInputChange(event) {
console.log(event.target.value);
}
render() {
return (
<div className="semantic ui segment">
<form className="ui form">
<div className="field">
<label>Image Search</label>
<input type="text" onChange={(event) => console.log(event.target.value)} />
</div>
</form>
</div>
);
}
}
export default AddFishForm;
当事件处理程序方法中的逻辑行不多时,这种方法非常有用。
现在,在我在render()
方法内提供的示例中,我有一个不受控制的表单元素。通常,作为开发人员,我们希望使用受控表单元素。因此,我将对其进行重构,以便您可以看到不同之处。
之所以提出这一点,是因为我看到在您的事件处理程序中您实现了this.setState(() => ({ title }));
,但是您想更加仔细地考虑实现,如果您的想法是拥有一个受控的表单元素,那么您希望实现该实现像这样:
class AddFishForm extends React.Component {
state = {
title: '',
amount: ''
};
}
createFish(event) {
event.preventDefault();
this.props.addFish({
url: this.state.url,
title: this.state.title
});
}
render () {
return (
<Segment>
<Form onSubmit={(e) => this.createFish(e)}>
<Form.Group >
<Form.Input
type='text'
placeholder='picture url'
autoFocus
value={this.state.title}
onChange={(e) => this.setState({ title: e.target.value })}
width={6}
/>
<Form.Input
type='text'
placeholder='title'
autoFocus
value={this.state.amount}
onChange={(e) => this.setState({ amount: e.target.value })}
width={6}
/>
</Form.Group >
<Button fluid type='submit'>Submit</Button>
</Form>
</Segment>
)
}
}
因此,您将使用输入的当前值来更新title
和amount
属性。
那我们为什么要使用state
?为什么每次更改输入时都用setState()
更新状态,为什么还要传递一个称为value
的东西?
onChange
setState()
,它将状态更新为新的value
。因此this.state.title
将包含用户输入的内容。this.state.title
并将其分配给输入的value
道具,它将覆盖输入中已经存在的所有文本。可以通过给该值一个名为乱码的字符串来证明这一点:
class SearchBar extends React.Component {
state = { term: '' };
render() {
return (
<div className="semantic ui segment">
<form className="ui form">
<div className="field">
<label>Image Search</label>
<input type="text" value="gibberish" onChange={(e) => this.setState({ term: e.target.value })} />
</div>
</form>
</div>
);
}
}
当您在浏览器中转到表单时,您将看到乱码已经填充在那里。
因此,上面概述的五个步骤是受控元素的流程。