Проблема setState: DOM обновляется, но не отражается в пользовательском интерфейсе - PullRequest
0 голосов
/ 25 июня 2018

У меня есть компонент, внутри компонента есть два раскрывающихся списка. При выборе значения в раскрывающемся списке «имя» отображается раскрывающийся список «Значение».

Для этой цели я использую 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

Я прочитал много проблем с переполнением стека и пробовал другие способы обновления состояния, но тщетно. Подскажите, пожалуйста, что я делаю не так?

...