2017-01-21 3 views
0

У меня есть функция, называемая request, которая вызывает вызов AJAX API и возвращает некоторые данные JSON. RenderEntry создает компонент Entry, который в основном представляет собой div с элементом h3. Предполагается, что элемент h3 исходит из данных JSON, который возвращается с request.Неопределенный объект, возвращаемый функцией при вызове в другой функции

В RenderEntry, я пытаюсь вызвать request с id, который передается в нее, присвоить его постоянной data, а затем передать data.name в Entry в качестве опоры. data, однако, не определено.

По правде говоря, это мое приложение для борьбы с кулаком, которое я загрузил с помощью create-react-app. Я знаю, что request работает, когда вы передаете в него литерал id, но я не понимаю, почему он не работает в этой функции.

function Entry(props) { 
    return (
    <div> 
     <h3>{props.name}</h3> 
    </div> 
); 
} 

class App extends Component { 

    RenderEntry(id) { 
    const data = request(id); 

    console.log(request(id)); // undefined 
    console.log(data);   // undefined 

    return <Entry name={data.name}/> 
    } 

    render() { 
    return (
     this.RenderEntry(8000) 
    ); 
    } 
} 


function request(id) { 
    const base = 'https://url.com/' 
    const request = new XMLHttpRequest(); 

    request.open('GET', base + id, true); 

    request.onload = function() { 
    if (this.status >= 200 && this.status < 400) { 
     // Success! 
     const data = JSON.parse(this.response); 
     // console.log(data); 
     return data; 
    } else { 
     console.log('We reached our target server, but it returned an error!'); 
    } 
    }; 

    request.onerror = function() { 
    console.log('There was a connection error of some sort'); 
    }; 

    request.send(); 
} 
+1

запроса Ajax является функцией асинхронного –

+0

Вашего запроса (ID), вероятно, возвращает до фактического запрос завершен. – sheunis

+0

Я добавил функцию запроса (id). Я думал, что возвращение к успеху означает возвращение, когда запрос заканчивается? –

ответ

0

Пути думать посыл, OnLoad и OnError в XMLHttpRequest является то, что посыл инициирует запрос на получение информации. Эта информация вернется через некоторое время. Тем временем, функция, в которой она находится, завершается, и поскольку у вас нет возврата, она по умолчанию возвращает «undefined». Вот почему вы получаете «undefined» из вызова console.log (request (id)).

Когда данные окончательно восстановлены, вызывается функция onload() или onerror() (первая, если поиск был успешным, а последний - при возникновении ошибки. Эти функции вызываются из XMLHttpRequest не из вашего код и поэтому возврат в onload() не отображается вашим кодом.

Чтобы получить данные, вам необходимо будет предоставить функцию, которая будет вызываться, когда данные, наконец, прибудут - это называется " callback ', и она ссылается на любую функцию, которая вызывается после асинхронной операции (одна из которых запускается, но отвечает через некоторое время).

Функция request() требует некоторого незначительного c hanges как так:

function request(id, callback) { 
    const base = 'https://url.com/' 
    const request = new XMLHttpRequest(); 

    request.open('GET', base + id, true); 

    request.onload = function() { 
    if (this.status >= 200 && this.status < 400) { 
     // Success! 
     const data = JSON.parse(this.response); 
     // console.log(data); 
     callback(data); 
    } else { 
     console.log('We reached our target server, but it returned an error!'); 
    } 
    }; 

    request.onerror = function() { 
    console.log('There was a connection error of some sort'); 
    }; 

    request.send(); 
} 

Теперь вызывать эту функцию, вы можете сделать что-то вроде этого:

function showData(data) { 
    console.log(data); 
} 
request(id, showData); 

Это должно отображать данные в консоли.

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

Неслучайно передавать две функции обратного вызова функции управления XMLHttpRequest (request() в вашем случае) - вызывается, если данные успешно извлекаются, а другая - в случае возникновения ошибки. Что-то вроде этого:

function showData(data) { 
    console.log(data); 
} 
function reportError(errResponse) { 
    console.warn(errResponse); 
} 
request(id, showData, reportError); 

Или пройти один обратный вызов, который принимает два параметра, один за ошибки и один для данных в случае успеха.Что-то вроде этого:

function receiveData(errResponse, data) { 
    if (errResponse) { 
    console.warn(errResponse); 
    } 
    else { 
    console.log(data); 
    } 
} 

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

callback(null, data); // if you get the data successfully 

    callback("Unable to retrieve data"); // if you get an error 

Вот link с более подробной информацией о получении данных от XMLHttpRequest и another о получении информации о различии между асинхронными и синхронными вызовами функций.

0

Вот как код должен быть:

function Entry(props) { 
    return (
    <div> 
     <h3>{props.name}</h3> 
    </div> 
); 
} 

class App extends Component { 
    constructor(...args){ 
    super(...args) 
    this.state = {} 
    request(8000); 
    } 

    render() { 
    if(this.state.error) return (..error view) 
    if(!this.state.data) return (..empty view of loader) 
    return (<Entry name={this.state.data.name}/>) 
    } 
} 


function request(id) { 
    const base = 'https://url.com/' 
    const request = new XMLHttpRequest(); 

    request.open('GET', base + id, true); 

    request.onload = function() { 
    if (this.status >= 200 && this.status < 400) { 
     // Success! 
     const data = JSON.parse(this.response); 
     // console.log(data); 
     this.setState({data:data}) 
     return data; 
    } else { 
     console.log('We reached our target server, but it returned an error!'); 
     this.setState({error:'We reached our target server, but it returned an error!''}) 
    } 
    }; 

    request.onerror = function() { 
    console.log('There was a connection error of some sort'); 
    this.setState({error:'There was a connection error of some sort'}) 
    }; 

    request.send(); 
} 
+0

Если вы не привяжете функцию request() к приложению, это скорее всего относится к глобальному объекту «windows» и не даст желаемых результатов. Обратные вызовы более распространены и устраняют вложение знаний о внешних объектах (нет необходимости в запросе() знать что-либо о приложении). – rasmeister

Смежные вопросы