使用react如何获取保存在const中的select下拉列表的值?

时间:2018-10-22 21:09:17

标签: javascript reactjs

我正在学习React。我试图将组件保留在单独的文件中。所以,我有:

  1. SaveDocument(类)
  2. PersonList(const)
  3. 人员(常量)

PersonList代表人员下拉列表。我试图弄清楚如何在SaveDocument类中获取选择下拉列表的值(即当他们单击“保存更改”时)。

当用户单击“保存”时,如何获得选择下拉列表的值?

以下代码:

PersonList.js

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;

Person.js

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;

SaveDocument.js

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">&times;</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;

2 个答案:

答案 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。