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?