#node.js #reactjs
#node.js #reactjs
Вопрос:
import React from 'react';
import './App.css';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
items: [],
isLoaded: false
};
}
callAPI() {
fetch("http://localhost:4000/api/process/4570")
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
items: result.items
});
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
this.setState({
isLoaded: false,
error
});
}
)
}
componetDidMount() {
this.callAPI();
}
render() {
var { error, isLoaded, items } = this.state;
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
}
else {
return (
<div className="App">
<ul>
{items.map(item => (
<li key={item.id} >
Id: {item.id} | Name: {item.name}
</li>
))}
</ul>
</div>
);
}
}
}
export default App;
консоль: ошибки нет.
react-developer-tool: возвращает
состояние =
{
«ошибка»: null,
«элементы»: [],
«isLoaded»: false
}
Я очень новичок в REACT и API. Пожалуйста, объясните мне, какую ошибку я допустил здесь. Я не могу получить вывод API. Я всегда получаю «загрузку»
API возвращает json: {«id»:»4570″,»name»:»AR_RESUME_CNC_ROUTING»}
Ответ №1:
вам нужно установить isLoading
значение true в вашей callApi
функции перед всем остальным, после этого вам нужно установить значение false при получении результата или при обнаружении какой-либо ошибки.
callAPI() {
this.setState({
isLoading: true,
});
fetch("http://localhost:4000/api/process/4570")
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoading: false,
items: result.items
});
},
(error) => {
this.setState({
isLoading: false,
error
});
}
)
}
небольшое объяснение кода, вы всегда хотите показывать загрузку при начале вашего вызова api, поэтому мы устанавливаем isLoading
в начале функции, затем, когда мы получаем результат (успех или неудача, не имеет значения), состояние загрузки должно измениться на false, потому что у нас есть хотя бы результат!
также в качестве дополнительного момента вы можете использовать try {...} catch {...} finally {...}
лучший стиль кода, как показано ниже:
async callApi() {
try {
this.setState({ isLoading: true })
const result = await fetch("http://localhost:4000/api/process/4570")
const data = await result.json()
this.setState({
items: result.items
});
} catch (e) {
this.setState({ error: e })
} finally {
this.setState({ isLoading: false })
}
}
Комментарии:
1. Обратите внимание, что это
isLoaded
, а неisLoading
🙂2. также вам необходимо изменить значение
else if (!isLoaded) {
наelse if (isLoaded) {
3. Я имел в виду, что переменная, используемая в вопросе, не представляет «загружается в данный момент», а «завершила загрузку» — полная противоположность вашему примеру.
Ответ №2:
Мне кажется, это какая-то проблема с областью действия. Вы делаете:
this.setState({
isLoaded: true,
items: result.items
});
но вы вызываете его в рамках обратного вызова функции обещания выборки. Итак, this
вероятно, ссылается на внутренний объект Promise.
Я рекомендую вам попробовать это:
callAPI() {
const self = this;
fetch("http://localhost:4000/api/process/4570")
.then(res => res.json())
.then(
(result) => {
self.setState({
isLoaded: true,
items: result.items
});
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
self.setState({
isLoaded: false,
error
});
}
)
}
Повторно ссылайтесь на this, на новую переменную (в данном случае я использовал self) и попробуйте свой код там.
Ответ №3:
Спасибо за ваш ответ, однако решение, которое сработало для меня, выглядит следующим образом:
class GetOnlinePosts extends Component {
constructor(props) {
super(props);
this.state = {
error: null,
loading: true,
posts: null,
};
}
async componentDidMount() {
console.log("inside external_json");
const url = "http://localhost:4000/api/process/4570";
const response = await fetch(url);
const data = await response.json();
this.setState({ posts: data, loading: false })
console.log(data);
}
………..