我正在学习React。我试图将组件保留在单独的文件中。所以,我有:
PersonList代表人员下拉列表。我试图弄清楚如何在SaveDocument类中获取选择下拉列表的值(即当他们单击“保存更改”时)。
当用户单击“保存”时,如何获得选择下拉列表的值?
以下代码:
import React from "react";
import Person from "./../model/Person";
const PersonList = props => {
return (
<div key="PersonList">
<select className="col-6">
{props.persons.map(person => <Person key={person.id} {...person} />)}
</select>
</div>
);
};
export default PersonList;
import React from "react";
import moment from "moment";
import "react-datepicker/dist/react-datepicker.css";
const Person = person => {
console.log(JSON.stringify(person));
return (
<option id="{person.id}">{person.firstName + " " + person.lastName}</option>
);
};
Document.defaultProps = {
firstName: "",
lastName: ""
};
export default Person;
import React, { Component } from "react";
import postDocument from "./../rest/PostDocument";
import fetchPersons from "./../rest/FetchPersons";
import PersonList from "./../components/PersonList";
import ShowDatePicker from "./../components/ShowDatePicker";
class SaveDocument extends Component {
state = {
persons: [],
personFromSelect: ''
};
cachePersons = personInfo => {
console.log(">> persons" + personInfo);
this.setState(prevState => ({
persons: personInfo
}));
};
resetFields () {
console.log("reset");
console.log(this.keys.PersonList.value);
}
componentWillMount() {
console.log("mounted");
fetchPersons.callApi(this.cachePersons);
}
render() {
return (
<div
className="modal fade"
id="basicExampleModal"
tabIndex="-1"
role="dialog"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
>
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title" id="exampleModalLabel">
Save document
</h5>
<button
type="button"
className="close"
data-dismiss="modal"
aria-label="Close"
>
<span aria-hidden="true">×</span>
</button>
</div>
<div className="modal-body">
<div className="row">
<div className="col-4 text-left">Document Date:</div>
<div className="col-6">
<ShowDatePicker />
</div>
</div>
<br />
<div className="row">
<div className="col-4 text-left">Person From:</div>
<PersonList persons={this.state.persons} />
</div>
<br />
<div className="row">
<div className="col-4 text-left">Comments:</div>
<div className="col-md-6">
<div className="form-group">
<input
type="text"
className="form-control"
id="commentsBox"
placeholder="Comments"
onKeyPress={event => {
if (event.key === "Enter") {
}
}}
/>
</div>
</div>
</div>
</div>
<div className="modal-footer">
<button
type="button"
className="btn btn-secondary"
data-dismiss="modal"
onClick={() => this.resetFields()}
>
Close
</button>
<button
type="button"
className="btn btn-primary"
onClick={() => postDocument.callApi(this.props)}
>
Save changes
</button>
</div>
</div>
</div>
</div>
);
}
}
export default SaveDocument;
答案 0 :(得分:2)
通常不建议使用uncontrolled components(其中输入状态由DOM元素直接处理),这会使管理和推理应用状态变得更加困难。我建议您更改为controlled component,其中输入的状态由React管理,而DOM只是呈现该状态。
PersonList.js :
请注意,<select>
元素从props
接收其选择的值,以及当用户进行更改时的回调处理程序。
const PersonList = props => {
return (
<div key="PersonList">
<select className="col-6" value={this.props.value} onChange={this.props.onChangeCallback} >
{props.persons.map(person => <Person key={person.id} {...person} />)}
</select>
</div>
);
};
Person.js :
请注意,它现在有一个value
属性,以便onchange事件知道新值是什么,而<select>
知道根据value
显示哪个选项。
const Person = person => {
console.log(JSON.stringify(person));
return (
<option value={person.id} id="{person.id}">{person.firstName + " " + person.lastName}</option>
);
};
SaveDocument.js :
请注意,您现在将下拉选择状态保持为React状态,并将其与用于更新状态的回调处理程序一起传递给子组件PersonList。
...
onChangeCallback = (e) => {
this.setState({personValue: e.target.value});
}
cachePersons = personInfo => {
console.log(">> persons" + personInfo);
this.setState(prevState => ({
persons: personInfo,
personValue: personInfo[0].id
}));
};
render() {
...
<PersonList
persons={this.state.persons}
value={this.state.personValue}
onChangeCallback={this.onChangeCallback}
/>
...
}
现在,您实际上是在父组件SaveDocument中保留下拉菜单的选择状态,并将其向下传递到列表中。该列表仅使用适当选择的值(来自状态)呈现下拉菜单,并在更改时提供回调。现在,下拉菜单的状态位于React状态内,并且当用户单击“保存”按钮时,可以从SaveDocument内轻松访问该状态,而不是模棱两可地位于DOM元素中。
答案 1 :(得分:1)
将道具添加到PersonList:
<PersonList onChangePerson={this.props.onChangePerson} />
将onChangePerson的事件处理程序添加到SaveDocument.js,不要忘记将其绑定到构造函数中。
onChangePerson(event) {
var value = event.target.value
}
this.onChangePerson = this.onChangePerson.bind(this);
在选择项上添加onChange事件
<select onChange={this.props.onChangePerson}></select>
然后,您将在onChangePerson事件中设置State来保存当前选择的人,然后当用户单击“保存”时,您将引用this.state.selectedPerson。