简体   繁体   English

如何使用 componentDidMount() 发出多个 axios.get() 请求并将第一个响应值分配给第二个?

[英]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.

相关问题 如何根据第一个下拉值使第二个下拉列表自动选择值 - How to make 2nd drop down list auto select value based on 1st drop down value 如何根据从第一个下拉菜单自动更改的第二个下拉菜单更改第二个文本框的值? - How to change the 2nd textbox value based on the 2nd dropdown that is automatically changed from 1st dropdown? 在第二个GET请求之后,第一页中的PHP会话变量的值未更新为第二页中的会话变量的值 - PHP session variable's value in 1st page not updating to value of session variable in 2nd page after 2nd GET request 有没有办法使用第一个数组作为 Javascript 中的参考在第二个数组中获取相应的索引值? - Is there a way to get corresponding index value in a 2nd array using the 1st array as a reference in Javascript? 我怎样才能做到第二<script> wait for 1st <script> to finish? - How can I make 2nd <script> wait for 1st <script> to finish? 根据第一个下拉值清除第二个下拉值 - Clear 2nd Dropdown values based on 1st Dropdown value 在React中执行多个GET请求时处理第二响应 - handling 2nd response when doing multiple GET requests in React 如何 - 使第一个动态下拉列表必须从第二个下拉列表中进行选择? - How to - Make 1st dynamic dropdown MUST to select from 2nd dropdown? 如何在第一个异步方法完成后运行第二个异步方法 - How to make 2nd async method run after 1st async method has finished 当第二个中的第一个可观测值需要时,如何在angular2中链接两个可观测的对象 - How to chain two observables in angular2, when value of 1st observable need in 2nd one
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM