Я делаю вызов API, используя fetch().then()...
Получение ответа с помощью application/json, и я хочу сохранить данные из ответа внутри тегов html, вернуть их и показать пользователю.
Из API я получаю 25 результатов, но мне нужны только первые 6 (сделано это с помощью цикла for).
Что внутри console.info() Я хочу показать в коде, где комментарий «Результат должен быть здесь».
Могу ли я и как это сделать?
Код ниже.
Я хочу использовать его в Stateless/Functional Component, поэтому без обработки состояния.
Кстати. Я новичок во всем этом, поэтому, пожалуйста, будьте нежны. Спасибо!
const Related = props => {
const url = `/artist/${props.artistId}/related`;
const getRelatedArtists = () => {
fetch(url)
.then(res => res.json())
.then(res => {
var artist, name, numFans, img;
for (let i = 0; i < 6; i++) {
artist = res.data[i];
name = artist.name;
numFans = artist.nb_fan;
img = artist.picture;
console.info(`
<div>
<p>Name: ${name}</p>
<p>Fans: ${numFans}</p>
<img src=${img} alt=${name} />
</div>
`);
}
})
.catch(err => console.info(err));
};
return (
<div>
<p>Related artists</p>
<button onClick = {getRelatedArtists}>get</button>
{/* Result should be here */}
</div>
);
};
Результат, который я хочу, выглядит так: https://imgur.com/40dUyiw
@Sunil спасибо, например, но я хочу использовать его без состояния. Если это возможно (?)
Вы должны использовать либо состояние, либо хранилище. Если вы используете функциональный компонент, вы можете отправить действие редьюсеру, обновляющему ваш магазин (когда ваш вызов API завершен). Обновление магазина повторно отобразит пользовательский интерфейс с новыми данными. В более новых версиях реакции вы можете реагировать хуки, чтобы добиться того же внутри компонентов без сохранения состояния.
@Sunil да, я попробую с крючками
React очень сильно зависит от состояние и реквизит — либо реквизиты прошедший для компонента, либо внутреннее состояние поддерживается на единицу. В вашем примере, не зная подробностей, похоже, что единственным вариантом здесь будет использование состояние компонента. Это означает, что вы не можете использовать компонент без состояния, как минимум, вы будете смотреть на PureComponent
или Component
, т.е.
import React, { PureComponent } from 'react';
class Related extends PureComponent {
state = {
artists: null,
error: null
}
constructor(props) {
this.super();
this.url = `/artist/${props.artistId}/related`;
}
getRelatedArtists = async () => {
try {
const res = await fetch(this.url);
const json = await res.json();
this.setState({ artists: json.data, error: null });
} catch(e) {
console.error(e);
this.setState({ error: 'Unable to fetch artists' });
}
}
renderError() {
if (!this.state.error) return null;
return (
<span className = "error">{this.state.error}</span>
)
}
renderArtistList() {
if (!this.state.artists) return null;
return this.state.artists.map((x,i) => (
<div key = {i}>
<p>Name: ${x.name}</p>
<p>Fans: ${x.nb_fans}</p>
<img src=${x.picture} alt=${name} />
</div>
));
}
render() {
return (
<div>
<p>Related artists</p>
<button onClick = {this.getRelatedArtists}>get</button> {this.renderError()}
{this.renderArtistList()}
</div>
);
}
}
Если вы используете React 16.x, вам, возможно, следует подумать об использовании Хуки. Вот как это будет выглядеть как функциональный компонент
import React, { useState, useCallback } from 'react';
function Related(props) {
// setup state
const [artists, setArtists] = useState(null);
const [error, setError] = useState(null);
// setup click handler
const getRelatedArtists = useCallback(async () => {
try {
// fetch data from API
const res = await fetch(`/artist/${props.artistId}/related`);
const json = await res.json();
// set state
setArtists(json.data);
setError(null);
} catch(e) {
console.error(e);
setError('Unable to fetch artists');
}
}, [props.artistId]);
// setup render helper
function renderArtist(artist, key) {
return (
<div key = {key}>
<p>Name: ${artist.name}</p>
<p>Fans: ${artist.nb_fans}</p>
<img src=${artist.picture} alt=${artist.name} />
</div>
);
}
// render component
return (
<div>
<p>Related artists</p>
<button onClick = {getRelatedArtists}>get</button> {error}
{artists && artists.map(renderArtist)}
</div>
)
}
Привет @James, спасибо за помощь. Я включаю этот код с хуками React и получаю ошибку: Uncaught TypeError: artist.map не является функцией. что теперь? Вы можете объяснить это мне?
@Zrna как выглядит ответ сервера? Я предположил, что вы получаете список JSON, но, похоже, это не так.
@Zrna Zrna а, хорошо, вижу, что полезная нагрузка не совсем то, что я ожидал, похоже, у вас есть ответ на страницу. Я обновился, чтобы соответствовать.
Чувак, ты для меня спасатель. Это работает. Большое спасибо!
при использовании реакции, поэтому вам нужно использовать преимущества, которые предоставляет вам реакция, вы должны разделить свой код и сделать его пригодным для повторного использования.
во-вторых: для получения всего нескольких чисел из связанных сообщений из большого массива вам не нужно делать цикл, вы можете просто объявить переменную и сохранить в ней количество сообщений, которые вам нужно сохранить в ней
import React, {Component} from 'react';
import Post from './post/post'
class RelatedPosts extends Component{
state = {
realted: [],
}
componentDidMount(){
const url = `/artist/${props.artistId}/related`;
fetch(url)
.then(response=>{
const relatedPosts = response.data.slice(0 ,4),
latestRelatedPosts = relatedPosts.map(post=>{
return {
post
}
})
;
this.setState({
realted: latestRelatedPosts
});
}).catch(error=>{
console.info(error)
})
}
render() {
let relatedPosts = this.state.realted.map(realtedPost=>{
return (
<Post post = {realtedPost}/>
);
});
return (
<section className = "Posts">
<p>Related artists</p>
{relatedPosts}
</section>
);
}
}
export default RelatedPosts;
здесь я создал запрос в componentDidMount Lifecycle, потому что он вызывается сразу после того, как компонент вставлен в дерево, и вы можете найти дополнительную информацию здесь
и здесь я создам новый компонент, чтобы упростить код для обслуживания позже, если вы захотите что-то изменить позже, и я передам ему данные, которые приходят из ответа на мой запрос
import React from 'react';
const post = (props) => (
<article className = "relatedPost">
<h1>Name: {props.post.Name}</h1>
<h1>Fans: {props.post.numFans}</h1>
<img src = {img} alt = {name} />
</article>
);
export default post
Возможный дубликат В React, как показать данные из API в таблице HTML?