2016-08-05 7 views
3

Я очень новичок в React, и я пытаюсь вызвать данные с сервера с помощью fetch api.Извлечь данные с помощью React

Если я хочу сделать вспомогательный класс, чтобы получить данные, как этот один

import { Promise } from 'es6-promise'; 
 
import fetch from 'isomorphic-fetch'; 
 
let responseData = response => { 
 
    return response; 
 
}; 
 

 
let getData = (dataURL, headers) => { 
 
    let result = { 
 
    data: [], 
 
    message: '' 
 
    }; 
 
    if (dataURL === null || dataURL === undefined || dataURL === '') { 
 
    result.message = 'URL is not correct'; 
 
    responseData(result); 
 
    } 
 
    fetch(dataURL, headers) 
 
    .then(response =>{ 
 
     if (response.ok) { 
 
     response.json().then(data => { 
 
      result.data = data; 
 
      result.message = response.statusText; 
 
      responseData(result); 
 
     }); 
 
     }else{ 
 
     result.message = 'Network response was not ok.'; 
 
     responseData(result); 
 
     } 
 
    }) 
 
    .catch(err => console.log(err)); 
 
}; 
 

 
exports.responseData = responseData; 
 
exports.getData = getData;

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

Я положил вызов внутри componentDidMout, но к тому моменту, когда он будет выполнен, результатом будет всегда undefined.

componentDidMount() { 
 
    var self = this; 
 
    let result = util.getData('http://localhost:3001/menus'); 
 
    const { dispatch } = this.props; 
 
    // dispatch(menuActions.fetchMenusIfNeeded()); 
 
    if (result !== null && result !== undefined) { 
 
     if (this.isMounted()) { 
 
     this.setState({ 
 
      items: result.data.results 
 
     }); 
 
     } 
 
    } 
 
    }

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

EDIT 1: Обновите вспомогательный класс:

import { Promise } from 'es6-promise'; 
 
import fetch from 'isomorphic-fetch'; 
 

 

 
let getData = (dataURL, headers) => { 
 
    return fetch(dataURL, headers); 
 
}; 
 

 
exports.getData = getData;

Он всегда будет возвращать Promise таким образом я могу обработчик цепи для передачи данных в других компонентах. Единственная проблема, с которой мне нужно обработать сообщение, можно, читая объект Response в моих компонентах.

В React компонент:

componentWillMount() { 
 
    util.getData('http://localhost:3001/menus') 
 
     .then(response =>{ 
 
     if (response.ok) { 
 
      response.json().then(data => { 
 
      console.log(data); 
 
      this.setState({ 
 
       items: data.result 
 
      }); 
 
      }); 
 
     } 
 
     }) 
 
     .catch(err => console.log(err)); 
 
    }

Но всякий раз, когда он получил данные, функция render() уже закончена, я должен заставить его обновить снова?

+0

вы ничего не возвращает из 'функции getData', но даже если вы сделали вернуться' result', это асинхронная так вы не увидите 'result' в' componentDidMount'. –

+0

Я понял проблему, но всякий раз, когда я возвращаю 'Promise', как я должен сообщить React для обновления функций' render() '. –

+0

Статья, в которой ответы на все вопросы о том, как и когда извлекать данные в React: [Как получить данные в React] (https://www.robinwieruch.de/react-fetching-data/). Возможно, это помогает людям узнать об этом, когда они спотыкаются по этому вопросу. –

ответ

1

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

Вам нужно только изменить код для getData, чтобы он выполнял обратный вызов после завершения запроса. У вас есть два варианта.

  1. Сделать функцию getData принимает третий параметр callback и вызвать этот метод, как только вы обработать ответ. Это будет примерно выглядеть следующим образом:

let getData = (dataURL, headers, callback) => { 
    let result = { 
    data: [], 
    message: '' 
    }; 
    if (dataURL === null || dataURL === undefined || dataURL === '') { 
    result.message = 'URL is not correct'; 
    responseData(result); 
    } 
    fetch(dataURL, headers) 
    .then(response =>{ 
     if (response.ok) { 
     response.json().then(data => { 
      result.data = data; 
      result.message = response.statusText; 
      responseData(result); 
     }); 
     }else{ 
     result.message = 'Network response was not ok.'; 
     responseData(result); 
     } 
     callback(result); 
    }) 
    .catch(err => console.log(err)); 
}; 

Имейте в виду, что это не так, как фактическая реализация будет выглядеть. В случае исключения обратный вызов не будет вызываться, и вызывающий код никогда не узнает, что произошло. Но по сути, так оно и будет работать.

  1. Выполнение функции getData возвращает обещание, созданное API fetch. Это тот, который я использовал бы лично, потому что он выглядит более чистым, и я бы принимал обещания по обратным вызовам в любой день недели.

let getData = (dataURL, headers) => { 
    let result = { 
    data: [], 
    message: '' 
    }; 
    if (dataURL === null || dataURL === undefined || dataURL === '') { 
    result.message = 'URL is not correct'; 
    responseData(result); 
    } 
    return fetch(dataURL, headers) 
    .then(response =>{ 
     if (response.ok) { 
     response.json().then(data => { 
      result.data = data; 
      result.message = response.statusText; 
      responseData(result); 
     }); 
     }else{ 
     result.message = 'Network response was not ok.'; 
     responseData(result); 
     } 
     return result; 
    }) 
    .catch(err => console.log(err)); 
}; 

Просто добавив ключевое слово return бы вернуть обещание, и тогда вы могли бы цепи обработчиков для желания вашего сердца.

ОК, как мы это используем? На самом деле это довольно просто. Теперь у вас есть возможность сообщить методу getData что-то сделать после получения ответа (или поднятого исключения).

Как пример, вы можете сделать это в методе componentWillMount компонента React.

componentWillMount() { 
    getData('http://example.com', new Headers()) 
     .then(function(result) { 
      this.setState({ items: result }); 
     }); 
} 

Вы также можете контролировать панель загрузки, установив флаг в состоянии до запроса и сбросить его после запроса (с обратными вызовами, конечно).

+0

Если я не возвращаю выбор напрямую, я всегда получаю пустой объект или 'undefined', есть ли способ сделать« обещание »в этом случае? –

2

result - это не данные, это обещание, которое вы можете использовать для доступа к данным. Вам необходимо вернуть Promise из fetch, а также вернуть данные из вашего then в пределах getData и обновить код React.

GetData изменение

return fetch(dataURL, headers) 
    .then(response =>{ 
    if (response.ok) { 
     response.json().then(data => { 
     result.data = data; 
     result.message = response.statusText; 
     return responseData(result); 
     }); 
    } else { 
     result.message = 'Network response was not ok.'; 
     return responseData(result); 
    } 
    }) 
    .catch(err => console.log(err)); 

Реагировать Смените

componentDidMount() { 
    var self = this; 
    let result = util.getData('http://localhost:3001/menus'); 
    const { dispatch } = this.props; 
    // dispatch(menuActions.fetchMenusIfNeeded()); 
    result.then((data) => { 
     if (this.isMounted()) { 
     this.setState({ 
      items: data.results 
     }); 
     } 
    }); 
} 
+0

Спасибо за ваш ответ, я попытался поместить 'then()' для 'result', но' result' всегда 'undefined', должен ли я попытаться вернуть результат непосредственно из' fetch'? –

+0

Можете ли вы посмотреть мой отредактированный вызов функции? как я могу сообщить React о данных и обновить render() –

+0

Две мысли, убедитесь, что это условие истинно ?: 'if (response.ok) {', в любом случае, я думаю, проблема может заключаться в том, что вы инициализируют ваше состояние: 'data: []', но вы устанавливаете результат в состояние в 'items:'. Вероятно, вам нужно обновить до: 'this.setState ({data: data.results})', предполагая, что ваша функция рендеринга работает на 'data', а не' items' –

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