ShadowOfCasper
@ShadowOfCasper
Middle User Interface Web Developer

Почему не изменяется props компонентов модалки по обновлению из внешнего setState?

Возникла проблема в передаче данных из компонента шагов настройки системы в модальное окно.
Итак, дано
1) Модальное окно. Экспротится 3 класса.
- само модальное окно - React.Component
- обёртка класса пассящего пропсы из опций вызова для программного рендера
- обёртка класса пассящего пропсы спредом  {...this.props} - тоже React.Component, использующая апи портала

То есть вроде должно быть ок. Я могу отрендерить модалку и функционально - из какого-нибудь event, и завязаться на state в  jsx шаблоне.

2) Компонент шагов настройки системы
Это самая начинка раздела. В нём заложен непростой state. В текущем исполнении он весь описан вручную, но чуть позже подъедет сервер и мержиться стейт будет из props, которые расставит  apollo.

this.state = {
            steps: {
                [stepName]: {
                    status: "proccess",
                    forcedOpen: false,
                    summary: true,
                    places: {
                        [placeName]: {
                            label: "label",
                            logged: true,
                            openModal: false //  это способ рендера <ModalRenderer/> по условию bool state в шаблоне,
                            logFields: {
                                [fieldName]: {
                                    value: 'val'
                                }
                            }
                        }
                    }
                }

Везде где ключ в квадратных скобках - есть соседние объекты под разными ключами.  Для того, чтобы изменить стейт по нажатию на свитчер или кнопку, я получал его через полбэк, копировал, изменял и возвращал обратно. И везде это работало, а когда я к этому стейту привязал input  в модальном окне, onChange этого инпута срабатывает, вносит изменения в state, и даже render-функция снова выполняется, но prop value в Input не меняется
У меня возникает ощущение что что-то я недопонял в setState

ё
/* Это кусок render-функции корневого компонента роута, в котором проблема*/
render() {
...
      const renderLoginModalInners = (place, stepKey, placeKey) => {
            if (stepKey !== 'alreadyHasProfile') return false;
            return <div className='flex flex-col'>
                {Object.keys(place.logFields).map(key => {
                    if (key === 'clientID')console.log(this.state.steps[stepKey].places[placeKey].logFields[key].value)
                    // let field = place.logFields[key];
                    return <Input key={key} 
                        value={this.state.steps[stepKey].places[placeKey].logFields[key].value} 
                        onChange={this.bindPlaceLogField.bind(this, stepKey, placeKey, key)}/>
                })}
                <Button disabled={!this.isAllPlaceFieldsFilled.bind(this, place)}><Trans i18nKey='auth.action.logon'/></Button>
            </div>
        }
...
        const renderLogger = (place, stepKey, placeKey) => {
            if (!place.openLogger) return;
            return <ModalRenderer ...>{renderLoginModalInners(place, stepKey, placeKey)}</ModalRenderer>
        }
}


Ну и setState, которое я не знаю как подружить с ассоциативными массивами
bindPlaceLogField(stepKey, placeKey, fieldKey, event) {
        const value = event.target.value
        this.setState((state) => {
            console.log(state.steps[stepKey].places[placeKey].logFields[fieldKey].value)
            state.steps[stepKey].places[placeKey].logFields[fieldKey].value = value;
            return Object.assign(state)
        }, () => {
            console.log(this.state.steps[stepKey].places[placeKey].logFields[fieldKey].value)
        })
    }

    bindSwitchPlace(stepKey, placeKey, value) {
        this.setState((state) => {
            let newState = Object.assign(state);
            newState.steps[stepKey].places[placeKey].value = value;
            return newState;
        })
    }

    toggleLoginModal(stepKey, placeKey, value) {
        this.setState((state) => {
            state.steps[stepKey].places[placeKey].openLogger = value;
            return Object.assign(state)
        })
        /*вариант программного рендера. Сначала я отрендерил компонент программно, и подумал что в этом причина */
        // const {t} = this.props;
        // new ModalCaller({
        //     title: `${t('markets.step.loginModal.title')} ${place.label}`,
        //     children: this.renderLoginModalInners(place, stepKey, placeKey), эта функция была методом компонента и возвращала кусочек jsx
        // })
   }


все console.log отрабатывают в нужное время - onchange вызывает if (key === 'clientID') console.log  и value там уже изменённое, как и в updated-колбэке setState, но сам input не перерисовывается.
  • Вопрос задан
  • 229 просмотров
Пригласить эксперта
Ответы на вопрос 1
ShadowOfCasper
@ShadowOfCasper Автор вопроса
Middle User Interface Web Developer
Ребят, всё ок (почти)
Когда я подробно описал проблему - ну сами знаете, метод уточки.
Я приглянулся к input, в котором input value={this.props.value} и решил попробовать прокинуть value сквозь state, и это сработало. Хотя странно - инпуты в других разделах обновляются нормально.
Может мне кто-нибудь объяснить, что у вас тут в реакте происходит?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы