Как обновить переменную, которая была объявлена ​​вне обещания внутри обещания? - PullRequest
0 голосов
/ 25 марта 2020

В моем компоненте у меня есть переменная с именем destination, и я назначаю ее как пустую строку. Затем у меня есть функция, которая возвращает обещание, и я передаю ответ другой функции, где я затем использую возвращенный объект в Object.assign. Я использую новый объект для обновления переменной destination, созданной вне обещания.

render() {
        return (
            <div className='destinations-container'>
                {
                    Object.keys(this.state.destinations).map((id) => {
                        var destination = "";
                        getFormSchema(this.state.destinations[id].product_type)
            .then(
                (response) => {
                    let defaultConfig = setDefaultConfig(response.data);
                    destination = Object.assign(defaultConfig, this.state.destinations[id]);
                });
                        return <Widget name={destination.name}
                                       textlinks={this.createWidgetTextLinks(destination)}
                                       state={getDestinationState(this.state.metadata[id] || {})}>
                            <WidgetInfo>
                                {widgetOverviewStaticInformation(destination, this.state.productList)}
                                {metadataOverviewItemsToShow(this.state.metadata[id] || {})}
                            </WidgetInfo>
                            <EditDestinationForm destination={destination}/>;
                        </Widget>
                    })
                }
            </div>
        )
    }

Проблема состоит в том, что переменная назначения остается равной "" даже после присвоения ей объекта, возвращенного из Object.assign в обещании. Это заставляет меня поверить, что переменная destination внутри обещания и переменная destination, которую я назначил в качестве пустой строки вне обещания, - это две разные вещи.

Как обновить переменную, которую я объявил как пустая строка внутри обещания?

Ответы [ 3 ]

0 голосов
/ 25 марта 2020

Это проблема синхронизации: когда метод на карте возвращается, обещание не разрешается (они асинхронные). Я предлагаю вам использовать другой подход, используя внутреннее состояние компонента (обновлено в обратном вызове обещания):

// this can be in any method in the class, not just in render (it's better not to have it in render).
Promise.all(
    Object.keys(this.state.destinations)
        .map(id => getFormSchema(this.state.destinations[id].product_type))
).then(decoratedDestinations => this.setState({decoratedDestinations}));

//in the render:
return (
    <div className='destinations-container'>
        {this.state.decoratedDestinations.map(decoratedDestination => (
            <Widget name={decoratedDestination.name} ... >
                ...
            </Widget>
        )}
    </div>
);

Таким образом, когда разрешение обещаний реагирует, автоматически будет повторно отображаться ваш компонент со всеми данные вам нужны.

0 голосов
/ 25 марта 2020

Destination обновляется, просто не отображается. Вы возвращаетесь из этой функции до того, как обещание будет завершено, поэтому оно будет отображаться с любым значением, которое оно имеет. Я согласен с @imrok, у вас не должно быть этого обещания в рамках рендера. Получите обещание вне его и обновите состояние компонента после его завершения, что вызовет повторный рендеринг с желаемым значением.

0 голосов
/ 25 марта 2020

Переменная destination может иметь ожидаемое поведение.

Я задаю вам вопрос: откуда вы знаете, destination не обновляется?

  • Вы открыли отладчик и поместили точку останова в обратный вызов then?
  • Или вы пришли к выводу, что на основе значения, отображаемого в вашем окне браузера?

В эту секунду В этом случае я хотел бы, чтобы вы заметили, что ваше второе возвращение также не входит в обещание :

Оно, безусловно, отрисовывает компонент Widget до разрешения обещания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...