Состояние React компонента не сохраняется при render-ре

Всем привет, проблема вот в чем:
у меня есть родительский компонент в котором все находиться, в нем есть дочернии компоненты. Часть я должен показывать сразу, а часть потом. Так вот после того как я показываю первую часть пользователям и с помощью селекта выбираю данные, у меня этот компонент изменяет state для того что бы появились другие компоненты, но и из-за этого перерисовываются те которые были видны, тем самым селектор обновляется и не понятно что выбрал пользователь.

код.
CreateModalAddUser - главный компонент

<div className = "form-horizontal" id = "table" key = { this.props.role}>
   <CreateInputFields callback = {this.callbackInputFields}/>
   <CreateCompanyClient company = {companyClient} compenyId = {this.state.compenyId} callback = {this.callbackCompenyId}/>
   <CreateSubOwner role = {this.props.role} callback = {this.callbackSubOwner}/>
    {
        divStyle.display
            ?
            <div style={divStyle}>
                <CreateAccrole = {this.props.role} callback = {this.callbackAcc} />
            </div>
            : null

    }
</div>

Вот в CreateCompanyClient вся загвоздка

import React, {PureComponent} from 'react';

export default class CreateCompanyClient extends PureComponent {

    componentDidMount() {
        this.selector();
    }

    selector(){
        var company = this.props.company;
        var data = [];
        var self = this;

        if(company) {
            _.each(company, function (company, index) {
                data[index] = {
                    'id': company.id,
                    'text': company.name
                }
            });

            $("#selectCompany").select2({
                data: data
            }).change(function (event) {
                self.props.callback($(this).val());
            });
        }
    }
    render() {
        return (
            <div className="form-group">
                <div className="col-md-5">
                    <label>Выберете компанию</label>
                </div>
                <div className="col-md-6">
                    <select className="js-data-example-ajax" id = "selectCompany">
                        <option value="-1">Выберете компанию</option>
                    </select>
                </div>
            </div>
        )
    }
}

При выборе из селекта CreateCompanyClient данные, он возвращает колбэком данные в родителя CreateModalAddUser и там обновляется state.action при котором divStyle.display срабатывает в тру и все показывает, но и обновляет CreateCompanyClient. И из-за этого не понятно что в селекторе выбрал пользователь. Селектор используется select2.

Пробовал записывать в CreateModalAddUser данные селектора и передавать их props-ом в CreateCompanyClient и его записывать в value, но так не получилось.Поэтому решил использовать PureComponent, но он отрабатывает как и обычный Component.

Что я делаю не так?

select2 генерирует некоторый DOM, о котором не знает react. Проблема в том что реакт не умеет работать, обновлять тот DOM, который не сгенерирован react-ом.

Тебе нужно описать компонент select-а так, чтобы вместо подготовки данных

 _.each(company, function (company, index) {
                data[index] = {
                    'id': company.id,
                    'text': company.name
                }
            });

в подобном цикле ты генерировал react компоненты (optionselect-а). Грубый пример (может не заработать):

<select className="js-data-example-ajax" id = "selectCompany">
    <option value="-1">Выберете компанию</option>
    {this.props.company.map(({id, name}, companyIndex) => {
    	return (<option key={companyIndex} value={id}>{name}</option>)
    })}
</select>

А еще проще - возьми готовую react обертку select2 (я ею не пользовался, просто нагуглил) https://github.com/rkit/react-select2-wrapper, и показывай select с ее помощью.

1 лайк

Привет, да я решил проблему взяв готовый select2 - react-select2-wrapper
код CreateCompanyClient получился следующий

import React, {PureComponent} from 'react';
import Select2 from 'react-select2-wrapper'
import 'react-select2-wrapper/css/select2.css'

export default class CreateCompanyClient extends Component {

    constructor(props){
        super(props);
        this.state = {
            value : true,
            data  : null
        }
    }

    componentWillMount() {
        this.selector();
    }

    selector(){
        var company = this.props.company;
        var data = [];
        var self = this;

        if(company) {
            data[0] = {
                'id': '0',
                'text': 'Выберете компанию'
            };
            _.each(company, function (company, index) {
                data[index + 1] = {
                    'id': company.id,
                    'text': company.name
                }
            });

            this.state.data = data;
        }
    }

    render() {

        const {compenyId, onSelect} = this.props;

        return (
            <div className="form-group">
                <div className="col-md-5">
                    <label>Выберете компанию</label>
                </div>
                <div className="col-md-6">
                    <Select2
                        multiple={false}
                        data = { this.state.data}
                        style={{width: 250 + 'px', display: 'block'}}
                        onSelect={(e) => {
                            onSelect(e.target.value);
                        }}
                    />
                </div>

            </div>
        )
    }
}
1 лайк