React.ReactNode, React.ReactElement, JSX.Element là gì?

davidtran

David Tran

Posted on August 16, 2020

React.ReactNode, React.ReactElement, JSX.Element là gì?

Typing là một phần tất yếu của việc lập trình bằng typescript. Khi bạn import thư viện nào mà quên cài đặt mấy cái "@type/..." là bị VSCode complain ngay.

Tuy nhiên vì không ai viết document cho type nên chúng ta không hề biết sử dụng type nào cho từng loại biến. Developer phải từ mò mà không có hướng dẫn nào cả

Và cụ thể là khi sử dụng ReactJS với Typescript, có nhiều trường hợp bạn không biết phải sử dụng type nào để khai báo biến cho event hoặc cho các props.

Ngộ nghĩnh là việc sử dụng những type như React.ReactNode, React.ReactElement, JSX.Element đó hầu như đều mang lại kết quả như nhau, tuy nhiên thỉnh thoảng lại bị vscode báo lỗi. Vậy chúng khác nhau như thế nào và sử dụng sao cho đúng?

Để hiểu bọn này khác nhau thế nào, chúng ta sẽ làm 1 việc đơn giản là đọc source code:

Sau đây là phần định nghĩa của ReactElement:

interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
   type: T;
   props: P;
   key: Key | null;
}

Và đây là định nghĩ của JSX.Element:

interface Element extends React.ReactElement<any, any> { }

Vậy thì JSX.Element và React.ReactElement đều là một, và chúng ta dùng 2 cái này khi mà bạn muốn variable của mình nhận vào 1 React component.

Đối với React.ReactNode:

type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
type ReactChild = ReactElement | ReactText;
type ReactText = string | number;

Như vậy ta có thể thấy ReactNode có thể chấp nhận ReactElement, string, text, boolean, null, undefined. Chúng ta có thể dùng ReactNode để khi muốn sử dụng render props.

Chẳng hạn:

<MyElement header={MyHeader} />

Trong trường hợp này, nếu như bạn muốn header của mình flexible, có thể nhận được cả string hoặc là nhận được cả 1 React component khác vào thì tốt nhất type của header sẽ là ReactNode :)

💖 💪 🙅 🚩
davidtran
David Tran

Posted on August 16, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related