Рендеринг Реагирует компоненты с обещаниями в методе рендеринга

У меня есть компонент, который получает набор объектов как опоры и maps их к набору компонентов, которые представляются как дети родительского компонента. Мы используем изображения, сохраненные в WebSQL как массивы байтов. В map функция я получаю идентификатор изображения от объекта и выполняю асинхронный вызов к DAL для получения массива байтов для изображения. Моя проблема состоит в том, что я не могу распространить обещание в Реагировать, так как оно не было разработано для контакта с обещаниями в рендеринге (не насколько я могу сказать так или иначе). Я происхожу из a C# фон, таким образом, я предполагаю, что ищу что-то как await ключевое слово для пересинхронизации разветвленного кода.

map функция выглядит примерно так (упрощенная):

var items = this.props.items.map(function (item) {
        var imageSrc = Utils.getImageUrlById(item.get('ImageId')); // <-- this contains an async call
        return (
            <MenuItem text={item.get('ItemTitle')}
                      imageUrl={imageSrc} />
       );
    });

и getImageUrlById метод похож на это:

getImageUrlById(imageId) {
    return ImageStore.getImageById(imageId).then(function (imageObject) { //<-- getImageById returns a promise
       var completeUrl = getLocalImageUrl(imageObject.StandardConImage);
       return completeUrl;
    });
}

Это не работает, но я не знаю то, что я должен изменить для создания этой работы. Я пытался добавить другое обещание цепочке, но затем я получаю ошибку, потому что моя функция рендеринга возвращает обещание вместо легального JSX. Я думал, что, возможно, должен усилить один из React методы жизненного цикла для выборки данных, но так как мне нужно props чтобы уже быть там, я не могу выяснить, где я могу сделать это.

62
задан 20 October 2015 в 19:51

2 ответа

render() метод должен представить UI от this.props и this.state, так к асинхронным данным загрузки, можно использовать this.state для хранения imageId:imageUrl отображение.
Затем в Вашем componentDidMount() метод, можно заполнить imageUrl от imageId. Затем render() метод должен быть чистым и простым путем рендеринга this.state, объект

Вот является быстрым примером кода:
Примечание, которое эти this.state.imageUrls заполняется асинхронно, таким образом, представленный объект списка изображений появится один за другим после того, как его URL выбирается. Можно также инициализировать this.state.imageUrls со всем идентификатором изображения или индексом (без URL), этот способ, которым можно показать загрузчик, когда то изображение загружается.

constructor(props) {
    super(props)
    this.state = {
        imageUrls: []
    };
}

componentDidMount() {
    var self = this;
    this.props.items.map((item) => {
        ImageStore.getImageById(item.imageId).then(image => {
            var mapping = {id: item.imageId, url: image.url};
            var newUrls = self.state.imageUrls.slice();
            newUrls.push(mapping);

            self.setState({
                imageUrls: newUrls
            });
        })
    });
}

render() {
    return (<div>
        this.state.imageUrls.forEach(mapping => {
            <div>id: {mapping.id}, url: {mapping.url}`</div>
        })
        </div>
    );
}
78
ответ дан 31 October 2019 в 14:12

Или можно использовать реагировать-обещание:

Установка пакет:

npm i react-promise

И Ваш код посмотрит что-то как так:

import Async from 'react-promise'

var items = this.props.items.map(function (item) {
    var imageSrc = Utils.getImageUrlById(item.get('ImageId')); // <-- this contains an async call
    return (
        <Async promise={imageSrc} then={(val) => <MenuItem text={item.get('ItemTitle')} imageUrl={val}/>} />    
    );
});

Редактирование: октябрь 2019

последняя сборка реагировать-обещания обеспечивает рычаг, названный usePomise:

import usePromise from 'react-promise';

const ExampleWithAsync = (props) => {
  const {value, loading} = usePromise<string>(prom)
  if (loading) return null
  return <div>{value}</div>}
}

Полные документы: реагировать-обещание

19
ответ дан 31 October 2019 в 14:12

Другие вопросы по тегам:

Похожие вопросы: