[英]How to make multiple axios.get() requests with componentDidMount() and assign a response value of the 1st to the 2nd?
I am trying to build a web application with Wordpress REST API.我正在尝试使用 Wordpress REST ZDB974238714CA8DE634A7CE1D083A1 构建 web 应用程序。
I am making an initial GET request to an endpoint and parsing through the res.data
to get some values.我正在向端点发出初始 GET 请求并通过res.data
解析以获取一些值。 But, one of the values featured_media
is a parameter for the 2nd GET request I am trying to make.但是, featured_media
的值之一是我尝试发出的第二个 GET 请求的参数。 I am finding it difficult to get this value out of that state onto the second GET request.我发现很难从 state 到第二个 GET 请求中获取这个值。
Here are the states.以下是各州。
state = {
graduatepost: {},
category: '',
featured_media: '',
imgURL: '',
isLoaded: false
}
Here is componentDidMount()
这是componentDidMount()
componentDidMount() {
const { featured_media } = this.props;
axios.get(`http://localhost:8000/wp-json/wp/v2/blog/${this.props.match.params.id}`)
.then(res => this.setState({
graduatepost: res.data,
category: res.data.categories[0],
featured_media: res.data.featured_media,
isLoaded: true
}))
.catch(err => console.log(err));
const getImageURL = axios.get(`http://localhost:8000/wp-json/wp/v2/media/${featured_media}`);
Promise.all([getImageURL]).then(res => {
this.setState({
imgURL: res[0].data.media_details.sizes.full.source_url,
isLoaded: true
});
});
}
1st GET request: http://localhost:8000/wp-json/wp/v2/blog/${this.props.match.params.id}
第一个 GET 请求: http://localhost:8000/wp-json/wp/v2/blog/${this.props.match.params.id}
2nd GET request: http://localhost:8000/wp-json/wp/v2/media/${featured_media}
第二个 GET 请求: http://localhost:8000/wp-json/wp/v2/media/${featured_media}
As you can see the 2nd request requires the value featured_media
which is in the response of the 1st GET request.如您所见,第二个请求需要在第一个 GET 请求的响应中使用的值featured_media
。
I am rendering the component like this.我正在渲染这样的组件。
render() {
const { graduatepost, category, isLoaded, featured_media, imgURL } = this.state;
if(isLoaded) {
return (
<Styles>
<Fragment>
<Link to='/graduate-posts'>Go Back</Link> // Ignore this
<hr />
<h1>{graduatepost.title.rendered}</h1>
<div dangerouslySetInnerHTML={{__html: graduatepost.content.rendered}}></div>
<h4>Category: {category}</h4>
<h4>featured_media: {featured_media}</h4>
<h4>imgURL: {imgURL}</h4>
</Fragment>
</Styles>
)
}
return <h3>Loading...</h3> // Ignore this
}
When I do the render the component.当我渲染组件时。 There is a 404 console error for the 2nd GET request, which states.第二个 GET 请求出现 404 控制台错误,其中指出。
GET http://localhost:8000/wp-json/wp/v2/media/undefined 404 (Not Found)
Uncaught (in promise) Error: Request failed with status code 404
at createError (createError.js:16)
at settle (settle.js:17)
at XMLHttpRequest.handleLoad (xhr.js:61)
I am assuming this is because featured_media
is empty/undefined but I cannot figure out how to extract that value from the 1st GET request, response.我假设这是因为featured_media
为空/未定义,但我无法弄清楚如何从第一个 GET 请求响应中提取该值。
This may seem like an obvious one but I'm relatively new to working with React.js and APIs together.这似乎是一个显而易见的问题,但我对一起使用 React.js 和 API 还比较陌生。 Your help would be greatly appreciated.您的帮助将不胜感激。
Thank you.谢谢你。
Have you tried Async function?您是否尝试过异步 function? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
async componentDidMount() {
....
await axios.get ...
....
}
The best way to access the setted data immediately is to use callback
.立即访问设置数据的最佳方法是使用callback
。
this.setState
accept the callback as its second argument ( setState(updater, [callback])
), so we should make our second request in our callback
statement. this.setState
接受回调作为它的第二个参数( setState(updater, [callback])
),所以我们应该在callback
语句中发出第二个请求。
Your code should be something like this:你的代码应该是这样的:
axios
.get(`http://localhost:8000/wp-json/wp/v2/blog/${this.props.match.params.id}`)
.then((res) =>
this.setState(
{
graduatepost: res.data,
category: res.data.categories[0],
featured_media: res.data.featured_media,
isLoaded: true,
},
() =>
axios
.get(
`http://localhost:8000/wp-json/wp/v2/media/${this.state.featured_media}`
)
.then((res) => {
this.setState({
imgURL: res[0].data.media_details.sizes.full.source_url,
isLoaded: true,
})
})
)
)
.catch((err) => console.log(err))
Maybe request it in the response of the 1st axios.get
.也许在第一个axios.get
的响应中请求它。 The reason it isn't working is because this.setState
is an async function in React so it's undefined
when you access it immediately below.它不起作用的原因是因为this.setState
是 React 中的异步 function 所以当你在下面直接访问它时它是undefined
的。
Try something like:尝试类似:
axios.get(`http://localhost:8000/wp-json/wp/v2/blog/${this.props.match.params.id}`)
.then((res) => {
const state = {
graduatepost: res.data,
category: res.data.categories[0],
featured_media: res.data.featured_media,
isLoaded: true
}
this.setState(state)
return axios.get(`http://localhost:8000/wp-json/wp/v2/media/${state.featured_media}`);
})
.then((res) => {
// do something with res
})
.catch((err) => {
// handle err
});
I have prepared one example where it shows all users and if you click to see posts button, it will show all the posts for that user.我准备了一个示例,它显示所有用户,如果您单击查看帖子按钮,它将显示该用户的所有帖子。
App.js应用程序.js
class App extends React.Component {
render() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/posts">Posts</Link>
</li>
</ul>
<hr/>
<Switch>
<Route exact path="/">
<UserList/>
</Route>
<Route path="/posts">
<PostListPageByUser/>
</Route>
</Switch>
</div>
</Router>
);
}
}
export default App;
UserList Component用户列表组件
import React from 'react';
import axios from 'axios';
import PostListPageByUser from "./PostListPageByUser";
import {withRouter} from "react-router-dom";
class UserList extends React.Component {
state = {
users: [],
showPostList: false,
user: {}
};
componentDidMount() {
axios.get(`https://jsonplaceholder.typicode.com/users`)
.then(res => {
const users = res.data;
console.log(users);
this.setState({users});
})
}
handleClick = (user) => {
console.log(user);
this.setState({showPostList: true, user: user});
this.props.history.push({
pathname: '/posts',
user: user
});
};
render() {
return (
<div>
<ul>
{this.state.users ? this.state.users.map(user => <div key={user.id}>
<span style={{minWidth: 400}}>{user.name} </span>
<button onClick={() => {
this.handleClick(user)
}}>See Posts
</button>
</div>) : null}
</ul>
{this.state.showPostList ? <PostListPageByUser user={this.state.user}/> : null}
</div>
)
}
}
export default withRouter(UserList);
PostListByUser Component PostListByUser 组件
import React from "react";
import axios from 'axios';
import {withRouter} from "react-router-dom";
class PostListPageByUser extends React.Component {
signal = axios.CancelToken.source();
state = {
posts: [],
};
componentDidMount() {
if(!this.props.location.user){
alert('Please click see posts button');
this.props.history.push('/');
return;
}
axios.get(`https://jsonplaceholder.typicode.com/posts?userId=${this.props.location.user.id}`, {
cancelToken: this.signal.token,
})
.then(res => {
this.setState({posts: res.data});
console.log(res.data, 'Posts');
}).catch(err => {
console.log(err);
});
}
render() {
return (
<div>
<ul>
{
this.state.posts ? this.state.posts.map(post => <li key={post.id}>{post.title}</li>) : null
}
</ul>
</div>
)
}
}
export default withRouter(PostListPageByUser);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.