- vừa được xem lúc

Blog#250: Don't Blindly Trust Error Message Solutions: A Real-Life Example

0 0 14

Người đăng: NGUYỄN ANH TUẤN

Theo Viblo Asia

250

Hi, I'm Tuan, a Full-stack Web Developer from Tokyo 😊. Follow my blog to not miss out on useful and interesting articles in the future.

1. Introduction

I've been working with Next.js for about three months in my job. During that time, I encountered an error during development: "Text content does not match server-rendered HTML." Although solving the issue wasn't difficult, the solution I used was different from what I found through Google or what ChatGPT suggested. In this article, I will introduce the general solutions and the one I used, showing that simply searching for error messages might not always lead you to the best solution. Even if you're not familiar with React, you should be able to understand the overall idea.

2. The Code that Caused the Error

Here is a simplified version of the code that caused the error. This component uses Server-Side Rendering (SSR) to render the content. The code is designed to display a comment as-is when it's within 30 characters, and truncate it with "..." if it exceeds 30 characters.

function MyComponent({comment}) { const displayedComment = comment.length > 30 ? comment.slice(0, 30) + '...' : comment return <div>{displayedComment}</div>
}

3. The Error and General Solutions

The error "Text content does not match server-rendered HTML" occurs when there's a discrepancy between server-side and client-side rendering. Let's look at some common solutions found through Google or provided by ChatGPT.

3.1. Avoid using browser-only libraries or application code

window is only undefined on the server-side, so using it can cause a discrepancy between server and client rendering. One solution is to use useEffect() which is called after rendering.

import { useEffect, useState } from 'react'
function MyComponent() { const [color, setColor] = useState('blue') useEffect(() => setColor('red'), []) return <h1 className={`title ${color}`}>Hello World!</h1>
}

3.2. Use Dynamic Import for components you don't want to render server-side

If you don't want to render a component server-side, you can use the Dynamic Import feature.

import dynamic from 'next/dynamic' const DynamicHeader = dynamic(() => import('../components/header'), { ssr: false,
})

3.3. Correct the HTML structure according to content model rules

HTML tags have parent-child relationship limitations called content models. For example, using a div tag as a child of a p tag is incorrect. You can solve this by replacing the p tag with a div tag.

export const CorrectComponent = () => { return ( <div> <div> This is correct and should work because a div is really good for this task. </div> <Image src="/vercel.svg" alt="" width="30" height="30" /> </div> )
}

3.4. Add an attribute to ignore the error

You can also use a JSX attribute to suppress the error, as shown in React's official documentation.

export default function App() { return ( <h1 suppressHydrationWarning={true}> Current Date: {new Date().toLocaleDateString()} </h1> );
}

4. The Solution I Adopted

In my case, the error occurred when a comment was truncated right at an emoji or a specific kanji character. These characters are represented by a combination of two special Unicode code points called surrogate pairs. When one of these pairs was cut off by .slice(), the error occurred. While the general solutions mentioned earlier did eliminate the error, they didn't fix the character corruption issue. The best solution was to adjust the character count logic to account for surrogate pairs. I used an array conversion method to handle this.

function MyComponent({comment}) { const displayedComment = [...comment].length > 30 ? [...comment].slice(0, 30).join('') + '...' : comment return <div>{displayedComment}</div>
}

However, this method still does not solve a case like the one below. If you have a better solution, please let me know.

const str = '👨‍👩‍👧‍👦';
[...str].slice(0, 5);
// Result: [ "👨", "‍", "👩", "‍", "👧" ]

Conclusion

This simple example demonstrates that the best solution for an error is not always the one found by searching the error message. Of course, it's essential to try the solutions you find, but understanding why the error occurs is also crucial. I hope this article helps you in your error-solving journey!

And Finally

As always, I hope you enjoyed this article and got something new. Thank you and see you in the next articles!

If you liked this article, please give me a like and subscribe to support me. Thank you. 😊

Ref

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 499

- vừa được xem lúc

Bạn đã biết các tips này khi làm việc với chuỗi trong JavaScript chưa ?

Hi xin chào các bạn, tiếp tục chuỗi chủ đề về cái thằng JavaScript này, hôm nay mình sẽ giới thiệu cho các bạn một số thủ thuật hay ho khi làm việc với chuỗi trong JavaScript có thể bạn đã hoặc chưa từng dùng. Cụ thể như nào thì hãy cùng mình tìm hiểu trong bài viết này nhé (go).

0 0 414

- vừa được xem lúc

Một số phương thức với object trong Javascript

Trong Javascript có hỗ trợ các loại dữ liệu cơ bản là giống với hầu hết những ngôn ngữ lập trình khác. Bài viết này mình sẽ giới thiệu về Object và một số phương thức thường dùng với nó.

0 0 136

- vừa được xem lúc

Tìm hiểu về thư viện axios

Giới thiệu. Axios là gì? Axios là một thư viện HTTP Client dựa trên Promise.

0 0 117

- vừa được xem lúc

Imports và Exports trong JavaScript ES6

. Giới thiệu. ES6 cung cấp cho chúng ta import (nhập), export (xuất) các functions, biến từ module này sang module khác và sử dụng nó trong các file khác.

0 0 93

- vừa được xem lúc

Bài toán đọc số thành chữ (phần 2) - Hoàn chỉnh chương trình dưới 100 dòng code

Tiếp tục bài viết còn dang dở ở phần trước Phân tích bài toán đọc số thành chữ (phần 1) - Phân tích đề và những mảnh ghép đầu tiên. Bạn nào chưa đọc thì có thể xem ở link trên trước nhé.

0 0 229