У меня есть компонент, внутри компонента есть два раскрывающихся списка. При выборе значения в раскрывающемся списке «имя» отображается раскрывающийся список «Значение».
Для этой цели я использую setState. При выборе состояние обновляется, компонент отображается, я могу видеть изменения в состоянии с помощью журнала консоли внутри render (). В браузере отражается, что DOM добавил еще один выпадающий список. Но это не видно в пользовательском интерфейсе.
Я использую setState, поскольку хочу обновить состояние хранилища только после того, как изменения будут завершены нажатием кнопки «Сохранить». При нажатии «отмена» изменения состояния компонента возвращаются обратно в состояние сохранения, которое я сохранил в переменной «Уже_выбранные_детали».
Но ни одно из этих изменений не отражено в пользовательском интерфейсе (но они отражены в DOM).
import React, { Component } from 'react'
import Dropdown from './Dropdown'
import Modal from './Modal'
import { findDOMNode } from 'react-dom'
let already_selected_details=[];
class CarInfo extends Component {
constructor(props) {
super(props);
this.state = {
details: []
};
}
componentWillMount() {
this.state.details = this.props.details;
}
componentDidMount() {
var nameElement = findDOMNode(this.refs.nameBox);
$(nameElement).on('change',this.handleSelectChange.bind(this));
var valueElement = findDOMNode(this.refs.valueBox);
$(valueElement).on('change',this.handleSelectChange.bind(this));
}
handleClick(event) {
this.props.actions.getDetails();
this.props.actions.toggleDisplayModal();
already_selected_details = this.state.details;
}
handleSelectChange(event) {
let id = event.target.isd;
let fn = id.split('_')[0];
id = parseInt(id.split('_')[1]);
if(fn == "name") {
let value = event.target.value;
this.setState({
details: this.state.details.map((detail, idx) => {
return idx==id ? Object.assign({}, detail, {name: value}) : detail;
})
});
}
else if(fn =="value") {
let value = [].filter.call(event.target.options, function (option) {
return option.selected;
}).map(function (option) {
return option.value;
});
this.state.details[id].value = value;
this.setState({
details: this.state.details
})
}
}
cancelSelection() {
this.setState({
details: already_selected_details
}, () => {
this.props.actions.toggleDisplayModal();
})
}
updateSelection() {
this.props.actions.setDetails(this.state.details);
this.props.actions.toggleDisplayModal();
}
render() {
return (
<div className="row">
<a className="clickable" onClick={this.handleClick.bind(this)}><span>{this.props.details.length==1 && this.props.details[0].name=="" ? "ADD " : "EDIT "}</span><span>DETAILS</span></a>
{
this.props.displayModal ?
<Modal>
<div className="modal">
<div className="modal-header">Select Details</div>
<div className="modal-body">{
this.state.details.map((detail, index) => {
console.log(index, detail.name, detail.value);
return (
<div>
<Dropdown class_name="col s12 m6 l3">
<div className={"input-field col s12"}>
<select className={detail.name!="" ? "dropdown-select" : "dropdown-select initial"} ref="nameBox" id={"name_"+index} defaultValue={detail.name!="" ? detail.name : ""}>
<option value="" disabled>Select Name</option>
{
Object.keys(this.props.attributes.details).map((detail_name) => {
return <option value={detail_name} key={detail_name}>{detail_name}</option>
})
}
</select>
<label></label>
</div>
</Dropdown>
{
detail.name !== "" ?
<Dropdown class_name="col s12 m6 l3">
<div className={"input-field col s12"}>
<select multiple className={detail.value==="" ? "dropdown-select initial" : "dropdown-select"} ref="valueBox" id={"value_"+index} defaultValue={detail.value==="" ? "" : detail.value}>
<option value="" disabled>Select Value</option>
{
detail.name !== "" ?
this.props.attributes.details[detail.name].map((detail_value) => {
return <option value={detail_value} key={detail_value}>{detail_value}</option>
})
: null
}
</select>
<label></label>
</div>
</Dropdown>
: null
}
</div>
)
})
}</div>
<div className="modal-footer">
<div className="row">
<div className="col s12 m5"><a className="btn" onClick={this.cancelSelection.bind(this)}>Cancel</a></div>
<div className="col s12 m7"><a className="btn" onClick={this.updateSelection.bind(this)}>Save</a></div>
</div>
</div>
</div>
</Modal>
: null
}
</div>
)
}
}
export default CarInfo
Компонент раскрывающегося списка:
import React, {Component} from 'react'
class Dropdown extends Component {
render() {
return (
<div className={this.props.class_name}>{this.props.children}</div>
)
}
}
export default Dropdown
Я прочитал много проблем с переполнением стека и пробовал другие способы обновления состояния, но тщетно.
Подскажите, пожалуйста, что я делаю не так?