Nano Hash - криптовалюты, майнинг, программирование

Render ничего не возвращает при использовании обещания

Я пытаюсь реализовать свою функцию рендеринга, чтобы она ждала, пока я закончу либо очистку данных из Интернета (если AsyncStorage его не имеет), либо извлеку их из AsyncStorage, но я борюсь с аспектом обещания:

render() {
    let pic = {
        uri: 'https://i.imgur.com/G19Jnuj.jpg'
    };
    this.renderAttributes()
        .then((response) => {
            console.log("finished val: " + this.state.name);
            console.log("finished response: " + response);
            return (
                <View style={shared.basicView}>
                    <Image source={pic} style ={styles.circleImage}/>
                    <Text style={styles.infoText}>{this.state.name}</Text>
                    <Text style={styles.titleText}>Bio</Text>
                    <Text style={styles.infoText}>blah blah</Text>
                    <Text style={styles.titleText}>Email</Text>
                    <Text style={styles.infoText}>blah blah</Text>
                    <Text style={styles.titleText}
                          onPress={() => this.props.navigation.navigate('Repositories')}>
                        Public Repos Count</Text>
                    <Text style={styles.infoText}>3</Text>
                    <Text style={styles.titleText}
                          onPress={() => this.props.navigation.navigate('Followers')}>
                        Follower Count</Text>
                    <Text style={styles.infoText}>0</Text>
                    <Text style={styles.titleText}
                          onPress={() => this.props.navigation.navigate('Following')}>
                        Following Count</Text>
                    <Text style={styles.infoText}>0</Text>
                    <Text style={styles.titleText}>Profile Created</Text>
                    <Text style={styles.infoText}>November 2015</Text>
                </View>
            )
        })
        .catch((error) => {
            console.log("Profile creation failed: " + error);
            return(null);
        })
}

Остальная часть класса и функция renderAttributes определены следующим образом:

class ProfileScreen extends Component {
    state: any;

    constructor(props) {
        super(props);
        this.state = {
            name: '',
            bio: '',
            email: '',
            repoCount: '',
            followerCount: '',
            followingCount: '',
            profileCreated: ''
        };
        this.renderAttributes = this.renderAttributes.bind(this);
    }

    async renderAttributes() {
        console.log("inside ga");
        let jsonData=null;
        try {
            axios.get('https://api.github.com/users/dummy')
                .then(async (response) => {
                    console.log("Response: " + JSON.stringify(response));
                    jsonData=response;
                    console.log("jsonData: " + JSON.stringify(jsonData));

                    const nameVal = await AsyncStorage.getItem('name');
                    if(nameVal !== null) {
                        console.log("name val: " + nameVal);
                        this.setState({name: nameVal});
                    }
                    else {
                        try {
                            await AsyncStorage.setItem('name', jsonData.data.name);
                        }
                        catch (error) {
                            console.log("Set name error: " + error);
                        }

                        if(jsonData.data.name == null) {
                            this.setState({name: 'n/a'});
                        }
                        else {
                            console.log("name: " + jsonData.data.name);
                            this.setState({name: jsonData.data.name});
                        }
                    }

                    const bio = await AsyncStorage.getItem('bio');
                    if(bio !== null) {
                        this.setState({bio: bio});
                    }
                    else {
                        try {
                            await AsyncStorage.setItem('bio', jsonData.data.bio);
                        }
                        catch (error) {
                            console.log(error);
                        }
                        if(jsonData.data.bio == null) {
                            this.setState({bio: 'n/a'});
                        }
                        else {
                            this.setState({bio: jsonData.data.bio});
                        }
                    }
                    // etc for each attribute in state
                })
                .catch((error) => {
                    console.log('Error fetching: ' + error);
                });

        }
        catch (error) {
            console.log('Error creating attributes: ' + error);
        }
    }

(Извините за все мои заявления console.log). Мне кажется, что это должно либо возвращать значение null, либо возвращать представление, несмотря ни на что, но я продолжаю получать сообщение об ошибке "Invariant Violation: ProfileScreen(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.". Ни один из моих операторов catch не запускается. Я честно сбит с толку; есть две вещи, которые я заметил, хотя они могут быть виновниками: 1. моя IDE выделяет this.state.name как неразрешенное имя переменной, 2. я явно не определил промис внутри renderAttributes (должен ли я?) . Кроме того, основываясь исключительно на операторах печати, кажется, что вещи внутри this.renderAttributes().then(response) печатаются до axios.get.then(); не уверен, что это отвлекающий маневр. Какие-либо предложения?


  • Я не реагирующий пользователь, но с тех пор, как я в последний раз играл с ним, render не было операцией async, для обработки async вы должны были изменить state, это затем вызвало бы метод render, и это из состояния, которое вы обновили бы Посмотреть. 27.03.2018
  • @ Кит, хм, наверное, я так и думал. Это определенно вопрос новичка, но какое значение имеет то, что рендеринг не является асинхронным? Если я заставлю его ждать renderAttributes(), разве этого не будет достаточно? 27.03.2018
  • I guess that's what I thought I was doing, как только вы используете промисы, асинхронность/ожидание/обратные вызовы и т. д., вы используете асинхронность.. ps. когда вы что-то await не превращаете в sync метод. 27.03.2018

Ответы:


1

Проблема здесь в том, что вы пытаетесь разрешить промис внутри функции render(), а сам промис асинхронный, и вы ничего не возвращаете, поэтому неявно вернете undefined.

Функция рендеринга должна быть чистой, без каких-либо побочных эффектов.

вы должны поместить асинхронную логику для извлечения ваших данных внутри одного из хуков жизненного цикла реакции, например componentWillMount() или componentDidMount()

https://reactjs.org/docs/state-and-lifecycle.html

27.03.2018
  • Хорошо, я прочитал документы и хочу убедиться, что правильно понял; Я должен принять вызов renderAttributes из render и просто вернуть представление с this.state.<attributeName> в качестве значений моих элементов. Затем в componentDidMount я должен вызвать renderAttributes, что вызовет «переоценку» рендеринга с обновленными значениями состояния? 27.03.2018
  • именно нечистая логика, содержащаяся в вашем renderAttributes(), должна быть помещена в один из хуков жизненного цикла, таких как componentDidMount(), когда обещание разрешено, вы устанавливаете состояние, и это вызовет повторную визуализацию. 27.03.2018
  • редактировать: похоже, вызов componentWillMount был бы лучшей идеей, на самом деле 27.03.2018
  • здесь есть хорошее сравнение между ними: daveceddia.com/ 27.03.2018

  • 2

    На самом деле, лучшее место, как указано в документации, это componentDidMount< /сильный>

    Вы должны предоставить «экран загрузки» при первом запуске (например, пустые поля и/или счетчик), а когда данные извлекаются (все делается в componentDidMount) и устанавливается состояние, покажите его.

    componentWillMount:

    Избегайте введения каких-либо побочных эффектов или подписок в этом методе. Для таких случаев используйте вместо этого componentDidMount().

    компонентDidMount:

    componentDidMount() вызывается сразу после монтирования компонента. Инициализация, требующая узлов DOM, должна идти здесь. Если вам нужно загрузить данные с удаленной конечной точки, это хорошее место для создания экземпляра сетевого запроса.

    27.03.2018
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..


    © 2024 nano-hash.ru, Nano Hash - криптовалюты, майнинг, программирование