0

I would like to set state variable books as result of API. I cannot do it in componentDidMount, because I don't have token at the beginning and need it to get result from API. Nothing happens with state books when I run following code. If I put state.books=res.data before return I got a result, but after manually refresh page.

constructor(props) {
        super(props);
        this.state = {
            books: [],
        };
    }

and

static getDerivedStateFromProps(nextProps, state) {
        if (nextProps.token){
            axios.defaults.headers = {
                "Content-Type": "application/json",
                Authorization: "Token " + nextProps.token
            }
            axios.get('http://127.0.0.1:8000/api/book/own/')
                .then(res => {
                    return {
                        books: res.data,
                    }  
                }) 
       }

data from the API looks like:

{
  id: 66,
  isbn: "9780545010221",
  title: "Title",
  author: "Author,Author",
}

In the render method I call component with this.static.books data.

Could you please advise me?

Maifee Ul Asad
  • 3,992
  • 6
  • 38
  • 86
S.P
  • 73
  • 5
  • `state.books` is an array and `res.data` seems to be an object. – Clarity Jan 21 '20 at 18:56
  • 2
    Don't fetch in `getDerivedStateFromProps`, use the other lifecycle hooks, like `componentDidUpdate`. – Emile Bergeron Jan 21 '20 at 18:58
  • Does this answer your question? [How to fetch data when a React component prop changes?](https://stackoverflow.com/questions/39000698/how-to-fetch-data-when-a-react-component-prop-changes) – Emile Bergeron Jan 21 '20 at 19:00
  • use `componentDidMount` and `componentDidUpdate`. getDerivedStateFromProps is for advanced use cases and not for doing async shit. – r3wt Jan 21 '20 at 19:03

1 Answers1

2

This is a very common pitfall: you are returning something inside the promise handler (then), thinking that that would return from the function that created the promise (getDerivedStateFromProps). That's not the case.

I'm afraid you can't use getDerivedStateFromProps for asynchronous code like this. However, you don't have to, given that react is, uhm, reactive.

componentDidUpdate() {
  if (this.props.token) {
    axios.get('http://127.0.0.1:8000/api/book/own/')
      .then(res => this.setState({books: res.data})) ;
  }
}
Christian Fritz
  • 20,641
  • 3
  • 42
  • 71