undefined не является функцией (оценка 'fetch('apiurl')')

Я использую следующие версии

  1. реагирующий поток-маршрутизатор ^ 3.39.1
  2. реактивный родной 0.44.0

Я ожидаю, что вызовет API, который я использую с «fetch». Использовал componentDidMount, но показывает другую ошибку

undefined не является объектом (оценка this._component.getScrollableNode)

Но я получаю ниже ошибок

введите здесь описание изображения введите здесь описание изображения

Действия по воспроизведению

  1. Создайте три сцены, используя поток маршрутизатора (в моем случае App, Login, Home)
  2. Используйте ScrollView для создания кнопки Login.js Create a button
  3. используя TouchableHighlight после этого вызовите выборку с помощью функции, использующей onPress, например onPress={ () => this.fetchData() }

Ниже код, который я использую для App.js

import React, { Component } from 'react';
import {
    View,
    Text,
    StyleSheet,
    AsyncStorage,
} from 'react-native';

import Login from './components/Login'
import Register from './components/Register'
import Home from './components/Home'
import { Scene, Router, TabBar, Modal, Schema, Actions, Reducer, ActionConst } from 'react-native-router-flux'

const reducerCreate = params=>{
    const defaultReducer = Reducer(params);
    return (state, action)=>{
        console.log("ACTION:", action);
        return defaultReducer(state, action);
    }
};

export default class App extends Component {

    constructor(props, context) {
        super(props, context);
        this.state = {
            logged: false,
            loading: true,
        };
    };

    componentWillMount(){
        self = this;
        AsyncStorage.getItem('token')
        .then( (value) =>{
            if (value != null){
                this.setState({
                    logged: true,
                    loading: false,
                });
            }
            else {
                this.setState({
                    loading: false,
                })
            }
        });
    };

    render() {
        if (this.state.loading) {
            return <View><Text>Loading</Text></View>;
        }
        return (
            <Router>
                <Scene hideNavBar={true} key="root">
                    <Scene key="logIn" component={Login} title="Login" initial={!this.state.logged}/>
                    <Scene key="regisTer" component={Register} title="Register"/>
                    <Scene key="home" component={Home} title="home"  initial={this.state.logged}/>
                </Scene>
            </Router>
        )
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
});

И ниже код, используемый для Login.js

/* @flow */

import React, { Component } from 'react';

import {
    View,
    StyleSheet,
    Image,
    ScrollView,
    TextInput,
    Text,
    TouchableHighlight,
    Alert,
} from 'react-native';
import { Container, Content, InputGroup, Input, Icon, Item } from 'native-base';
import Button from 'react-native-button'
import {Actions} from 'react-native-router-flux'
import ResponsiveImage from 'react-native-responsive-image'

export default class Login extends Component {

    constructor(props){
        super(props)
        this.state = {
            email: '',
            password: '',
            data: '',
        }
    }

    fetchData() {
        fetch('http://allstariq.tbltechnerds.com/api/login/?username=andress&password=23434')
        .then((response) => response.json())
        .then((responseData) => {
            this.setState({
                data: responseData.movies,
            });
        })
        .done();
    }

    render() {
        return (
            <View style={styles.container}>

            <ScrollView>

                <View style={ styles.logoContainer }>

                    <View style={{flexDirection: 'row',}}>
                        <ResponsiveImage
                        source={require('../assets/logo.png')}
                        initWidth="300"
                        initHeight="160" />
                    </View>

                </View>

                <View style={ styles.formContainer }>
                    <Item>
                        <Icon active name='mail' />
                        <Input
                            onChangeText={(text) => this.setState({email: text})}
                            value={this.state.email}
                            placeholder='Email'/>
                    </Item>

                    <Item>
                        <Icon active name='key' />
                        <Input
                            onChangeText={(text) => this.setState({password: text})}
                            value={this.state.password}
                            placeholder='Password'/>
                    </Item>
                    <TouchableHighlight
                        style={ styles.loginButton }
                        onPress={ () => this.fetchData() }>
                        <Text style={ styles.btnText}>Login</Text>
                    </TouchableHighlight>
                </View>

                <View style={ styles.bottomContainer }>
                    <Text style={ styles.cenText }>Dont worry if you haven't an account yet . . </Text>
                    <Text
                    style={ styles.blueText}
                    onPress={ Actions.regisTer }
                    >Register Now</Text>
                </View>

            </ScrollView>

            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
    logoContainer: {
        flex: .5,
        padding: 10,
        justifyContent: 'center',
        alignItems: 'center',
    },
    logoItem: {
        width: null,
        height: null,
        resizeMode: 'cover',
    },
    formContainer: {
        flex: 4,
        padding: 10,
    },
    inputelm: {
        marginBottom: 10,
        backgroundColor: '#999',
        borderWidth: 0,
        fontSize: 20,
        color: '#FFF',
        fontFamily: 'AmaticSC-Bold',
    },
    loginButton: {
        borderRadius: 3,
        marginBottom: 20,
        marginTop: 20,
        paddingLeft: 10,
        paddingRight: 10,
        backgroundColor: '#2196f3',
        elevation: 4,
    },
    signupButton: {
        borderRadius: 3,
        marginBottom: 20,
        marginTop: 20,
        paddingLeft: 10,
        paddingRight: 10,
        backgroundColor: '#7cb342',
        elevation: 4,
    },
    btnText: {
        textAlign: 'center',
        color: '#FFF',
        fontSize: 30,
        lineHeight: 40,
    },
    blueText: {
        textAlign: 'center',
        color: '#2196f3',
        fontSize: 20,
        lineHeight: 40,
    },
    bottomContainer: {
        flex: 1,
        padding: 10,
    },
    cenText: {
        textAlign: 'center',
        fontSize: 16,
    },
});

Каков фактический способ использования выборки с react-native-router-flux? Я новичок, чтобы реагировать, пожалуйста, помогите мне.


person Tareq Aziz    schedule 21.05.2017    source источник
comment
Добавление кода, который вы написали, поможет получить ответ   -  person Shubham Khatri    schedule 21.05.2017
comment
@ShubhamKhatri обновлен кодами   -  person Tareq Aziz    schedule 21.05.2017


Ответы (3)


Вы пытались, может быть, импортировать библиотеку?

Import fetch from "fetch";
person Tzook Bar Noy    schedule 21.05.2017

Вы не импортировали функцию fetch, импортируйте ее из модуля node-fetch, например

import fetch from 'node-fetch'
person Shubham Khatri    schedule 22.05.2017

ну, это на пару месяцев позже, но проблема здесь в том, что ваш метод fetchData не имеет доступа к этому, потому что когда вы объявляете такой метод:

fetchData() {

}

Под капотом react создает функцию следующим образом:

this.fetchData = function() {

}

когда вы объявляете функцию с помощью ключевого слова function, все, что находится между {}, будет иметь собственное «this», и ваш метод не будет иметь доступа к «this» контекста компонента.

Вот почему вы получаете «неопределенное», потому что вы вызываете «this.setState» внутри обещания, возвращаемого выборкой, поэтому ошибка не выборка, а это.

Чтобы решить эту проблему, вы можете просто определить свой метод следующим образом:

fetchData = () => {

}

А поскольку функции, определенные жирной стрелкой, не создают свою собственную область видимости, компонент this будет доступен внутри вашего метода.

person EnriqueDev    schedule 06.11.2017