0

I'm using prevProps and prevState in my componentDidUpdate method, but it says the variable book isn't defined. However, I've tried different ways of defining it that don't work. I've also seen examples where this is unnecessary. Can someone please take a look at this and let me know what I might be missing?

class Dashboard extends Component {

    state = {
        // book: this.props.book,
        book: '',
        info: this.props.info, 
        error: '',
    }

    // constructor(props) {
    //     super(props);
    //     this.state = {
    //         book: '',
    //         info: '',
    //         error: '',
    //     }
    //   }



async componentDidUpdate(prevProps, prevState) {
    // const book = this.props.book;
    // console.log(`book: ${book}`);
    if (prevProps.book !== this.props.book) {
        try{
            const data = await GoogleAPI.getBook(book);
            if (data.length > 0){
                this.setState({
                    book: book,
                    info: data, 
                })
            }
            else {
                this.setState({error: 'Book Not Found'})
            }
        }
        catch {
            // this.props.setModal('Offline');
        }
        }
        // console.log(`book check state: ${book}`);
        console.log(`prevProps: ${prevProps.book}`);
//Checking for book state here
            console.log(`book state: ${this.state.book}`);
    }
Elizabeth
  • 157
  • 1
  • 15

1 Answers1

0

Issue

book isn't defined, but props.book likely is.

Solution

Access this.props.book in the callback chain

async componentDidUpdate(prevProps, prevState) {
  if (prevProps.book !== this.props.book) {
    try {
      const data = await GoogleAPI.getBook(this.props.book); // <-- here
      if (data.length > 0) {
        this.setState({
          book: this.props.book, // <-- here
          info: data
        });
      } else {
        this.setState({ error: "Book Not Found" });
      }
    } catch {
      // this.props.setModal('Offline');
    }
  }
}

If you want to log updated state.book values then you need to add an additional condition block in componentDidUpdate to compare previous state to current state or use the setState callback.

if (prevState.book !== this.state.book) { 
  console.log(this.state.book); // <-- state updated from previous
}

or

this.setState(
  {
    book: this.props.book,
    info: data
  },
  () => console.log(this.state.book), // <-- runs after state updated
);
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Thank you Drew that worked. For some reason though, when I console log book state it doesn't update. Do you know why this might be happening? – Elizabeth Apr 08 '21 at 14:33
  • @Elizabeth Where are you logging `book`? If you are trying to log the state right after the `this.setState` it will only ever log the state from the current render cycle, not the `book` value you are enqueueing for the next render cycle. – Drew Reese Apr 08 '21 at 15:00
  • I added a note above in my original question where I'm checking for it – Elizabeth Apr 08 '21 at 16:57
  • @Elizabeth Yes, that is exactly what I meant by my previous comment. I updated my answer. – Drew Reese Apr 08 '21 at 17:15
  • Thanks, I tried both but it still doesn't update state. The console after setState doesn't register either – Elizabeth Apr 08 '21 at 17:57
  • @Elizabeth Well, React state updates are already processed asynchronously, and you've tagged `componentDidUpdate` to be `async` so that adds a level of complexity when trying to do any normal synchronous logic within the confines of a single render cycle. If you could create a *running* codesandbox example that reproduces this issue I can take a deeper look. – Drew Reese Apr 08 '21 at 18:02