Sunday 1 November 2020

next/link losing state when navigating to another page

I am developing a library Next.js application. For the purposes of this question, I have two pages in my application: BooksPage which lists all books, and BookPage which renders details of a book. In terms of components, I have a <Books /> component which renders a <Book /> component for every book in my library database.

Here are my components:

Books.js:

function Books({ books }) {
  return (
    <>
      {books.map(book => (
        <Book key={book.id} book={book} />
      ))}
    </>
  );
}

Book.js:

class Book extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = { liked: false };
  }

  like = () => {
    this.setState({ liked: this.state.liked ? false : true })
  };

  render() {
    return (
      <>
        <Link href={`/books/${book.slug}`}>
          <a>{book.title}</a>
        </Link>

        <Button onClick={this.like}>
          <LikeIcon
            className={this.state.liked ? "text-success" : "text-dark"}
          />
        </Button>
      </>
    );
  }
}

Problem:

Say that I am on page BooksPage. When I click the like button of a <Book /> the icon color toggles properly in the frontend and the like is successfully added or removed in the backend. When I refresh BooksPage all the state is maintained and consistent.

The problem arises when I like something on BooksPage and then immediately navigate to BookPage without refreshing using next/link. There the like button is not toggled consistently and the state from BooksPage is lost. Notice that if I hard-refresh the page everything goes back to normal.

Slow solution: Do not use next/link.

Replace

<Link href={`/books/${book.slug}`}>
  <a>{book.title}</a>
</Link>

with

<a href={`/books/${book.slug}`}>{book.title}</a>

Fast solution: Keep using next/link?

Is there a way to use next/link and maintain state when navigating to another pre-rendered route?



from next/link losing state when navigating to another page

No comments:

Post a Comment