У меня есть API, который предоставляет мне некоторые данные, которые я хочу отобразить на экране самым плавным способом.Моя идея заключалась в том, чтобы асинхронно получать данные из API и отображать их, как только я получу ответ от API.Сейчас это мой класс
import React, { Component, Fragment } from "react";
import Grid from "@material-ui/core/Grid";
import Typography from "@material-ui/core/Typography";
import Episode from "../components/Episode";
import PropTypes from "prop-types";
import { withStyles } from "@material-ui/core/styles";
import CircularProgress from "@material-ui/core/CircularProgress";
const styles = theme => ({
progress: {
display: "flex",
justifyContent: "center",
alignItems: "center"
},
text: {
marginTop: 20,
marginLeft: 30
}
});
class SeriesPage extends Component {
constructor(props) {
super(props);
this.state = {
apiToken: "",
serie: null,
episode: 1,
episodes: [],
endEpisode: 100
};
}
async componentDidMount() {
await this.getTokenFromApi();
await this.getSerieDetailsByApiName();
for(int i = 0; i< this.state.endEpisode; i++){
this.getSerieEpisode();
}
}
getTokenFromApi = async () => {
const data = {
name: "generateToken",
param: {
email: "-",
pass: "-"
}
};
return fetch("api", {
method: "post",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(data)
})
.then(response => {
if (!response.ok) {
this.setState({
episodes: "Network request failed"
});
throw Error("Network request failed");
}
return response;
})
.then(res => {
return res.json();
})
.then(content => {
if (content.response.status === 200) {
this.setState({
apiToken: content.response.result.token
});
}
})
.catch(error => {
this.setState({
episodes: "There was an internal error"
});
throw error;
});
};
getSerieDetailsByApiName = async () => {
const data = {
name: "getSerieDetailsByApiName",
param: {
serieApiName: this.props.match.params.series
}
};
return fetch("api", {
method: "post",
headers: {
Authorization: "Bearer " + this.state.apiToken,
"Content-Type": "application/json"
},
body: JSON.stringify(data)
})
.then(response => {
if (!response.ok) {
this.setState({
episodes: "Network request failed"
});
throw Error("Network request failed");
}
return response;
})
.then(response => {
return response.json(); //response.json() is resolving its promise. It waits for the body to load
})
.then(responseData => {
if (responseData.response.status === 200) {
this.setState({
serie: responseData.response.result
});
}
})
.catch(error => {
this.setState({
episodes: "There was an internal error"
});
throw error;
});
};
getSerieEpisode = async () => {
const data = {
name: "getEpisodeBySeriesApiName",
param: {
serieApiName: this.props.match.params.series,
ep: this.state.episode
}
};
console.log(data);
return fetch("api", {
method: "post",
headers: {
Authorization: "Bearer " + this.state.apiToken,
"Content-Type": "application/json"
},
body: JSON.stringify(data)
})
.then(response => {
if (!response.ok) {
this.setState({
episodes: "Network request failed"
});
throw Error("Network request failed");
}
return response;
})
.then(response => {
return response.json(); //response.json() is resolving its promise. It waits for the body to load
})
.then(responseData => {
console.log(responseData);
if (responseData.response.status === 200) {
this.setState(prevState => ({
episodes: [...prevState.episodes, responseData.response.result]
}));
}
})
.catch(error => {
this.setState({
episodes: "There was an internal error"
});
});
};
render() {
const { classes, theme } = this.props;
var series =
this.state.serie === "No results found" ? (
<Typography
className={classes.text}
component="h2"
variant="h5"
color="error"
gutterBottom
>
{this.state.serie}
</Typography>
) : this.state.episodes === "There was an internal error" ? (
<Typography
className={classes.text}
component="h2"
variant="h5"
color="error"
gutterBottom
>
{this.state.episodes}
</Typography>
) : (
this.state.episodes.map((item, i) => {
const { classes, headerIsHidden, ...other } = this.props;
return <Episode key={i} episode={item} {...other} />;
})
);
if (this.state.episodes) {
return (
<Fragment>
<div className="series">
<div className="container">
<Grid container spacing={24}>
{series}
{this.state.loadingState ? (
<p className="loading"> loading More Items..</p>
) : (
""
)}
</Grid>
</div>
</div>
</Fragment>
);
} else {
return (
<Grid className={classes.progress} item xs={12}>
<CircularProgress size={100} />
</Grid>
);
}
}
}
export default withStyles(styles, { withTheme: true })(SeriesPage);
По сути, этот класс извлекает данные из метода componentDidMount и запускает цикл for для каждого эпизода, пока он не достигнет конца, я чувствую, что это не лучший способ.Любые советы?