Câu hỏi phỏng vấn mẹo về React: Component hay element được render trong browser?

6157

Bạn có thể không thích câu trả lời vì thật sự rất phức tạp.

Isn’t the word element synonymous to the word component anyway?

Câu hỏi phỏng vấn mẹo về React: Component hay element được render trong browser?

From reactjs.org

Nói một cách kỹ thuật, ReactDOM không biểu thị một React component hoặc React element trong DOM. Nó render các phần tử DOM được hỗ trợ bởi instances của component. Điều này đúng cho các thành phần của class. Đối với function component, ReactDOM chỉ tạo ra các phần tử DOM. Function elements không có các instance (có thể được truy cập với this) vì vậy khi sử dụng một function component, ReactDOM render DOM element được tạo ra từ element được trả về của function.

Những gì bạn cần hiểu ở đây là một React element khác với một DOM element. React element chỉ là mô tả của một HTML element, React component, hoặc là sự kết hợp của cả hai.

Một câu hỏi phỏng vấn hay hơn sẽ là: “Khi nào bạn sử dụng một cái gì đó giống như <MyComponent /> trong JSX, một component, element hay một instance?”

Là element nhưng không phải là DOM element, mà là React element. Đầu mối ở đây là bất kỳ JSX tag nào được dịch sang React.createElement . Nhớ, CREATE. ELEMENT.

Tuy nhiên, đối với React để tiếp tục làm việc với React element này, nó sẽ phải đưa ra một function hoặc tạo instance từ class.

Bạn có thể tìm thấy các component, element, và instance bị hòa lẫn trong các React guides và hướng dẫn trên mạng. Tôi có lỗi về việc xáo trộn những từ ngữ này, nhưng tôi nghĩ một người mới bắt đầu học về React cần phải hiểu được những điểm khác biệt quan trọng. Blog React có một bài viết về chủ đề này nhưng lại quá kỹ thuật cho người mới bắt đầu.

Bạn có thể tham khảo những định nghĩa đơn giản hơn của tôi:

  • React Component là template. Một blueprint. Một global definition. Đây có thể là function hoặc class (với một chức năng render).
  • React Element là những gì được trả lại từ các component. Đó là một đối tượng hầu như mô tả các DOM nodes mà một thành phần đại diện. Với function component, element này là đối tượng mà hàm trả về. Với class component, Element là đối tượng mà hàm trả về của function returns. Các React element lại không phải là những gì chúng ta thấy trong trình duyệt. Chúng chỉ là những đối tượng trong bộ nhớ và không thể thay đổi bất cứ điều gì.
  • React tạo, cập nhật và hủy các instance nội bộ để tìm ra DOM element tree cần phải được render cho browser. Khi làm việc với các class components, thường thì sẽ tham chiếu đến các DOM element được render bằng browser như các component instances. Bạn có thể render cho nhiều instance của cùng một component. Instance là từ khóa “this” mà bạn sử dụng bên trong các thành phần dựa trên class. Bạn sẽ không cần phải tạoinstance từ class 1 cách thủ công, chỉ cần nhớ rằng nó nằm ở một nơi nào đó trong bộ nhớ của React.
  • Các phần tử React dựa trên chức năng không có instance. Một function component vẫn có thể được render nhiều lần nhưng React không chỉ kết hợp một local instance với mỗi lần biểu thị. Nó chỉ sử dụng chức năng gọi hàm để xác định DOM element nào sẽ hiển thị cho hàm.

Điểm mấu chốt là ReactDOM không hiển thị các component trong trình duyệt, và nó không biểu thị các phần tử hoặc (theo nghĩa giữ phần tử để đại diện cho kết quả của React.createElement). Nó cũng không thể hiện instance mà thể hiện các DOM element.

Thật không may, có vẻ như có một practice phổ biến là ở đó để sử dụng term component là cả template lẫn instances hoặc invocations được sử dụng thông qua templates. Tôi không đổ lỗi cho bất cứ ai vì bị lẫn lộn ở đây. Chỉ là một chút thất vọng.

Câu chuyện ở đây là gì?

Mỗi React app bắt đầu với một render sử dụng một phần tử React. Hãy dùng ví dụ HelloMessage  từ reactjs.org, thay đổi 1 chút để có function component:

const Today = () => (
 <div>Today is {new Date().toDateString()}</div>
);
class HelloMessage extends React.Component {
 render() {
   return (
     <React.Fragment>
       <div>Hello {this.props.name}</div>
       <Today />
     </React.Fragment>
   );
 }
}
ReactDOM.render(
 <HelloMessage name="Taylor" />,
 mountNode
);

React element đầu tiên là instance chúng ta bắt đầu trong ReactDOM.render call:

<HelloMessage name="Taylor" /> // This is a React element

React element này mô tả rằng DOM tree được kết xuất nên bắt đầu với component của HelloMessage và một biến  name  với giá trị prop tương đương với Taylor.

React bây giờ cần trả lời câu hỏi: HelloMessage là gì?

Mỗi lần React element mô tả 1 React component (giống như React element chúng ta có ở trên), React sử dụng component của nó để thay thế instance đó bằng những component được trả về. Nó tạo ra instance cho các component dựa vào class hiện tại và giữ tham chiếu của instance trong bộ nhớ và không tạo ra bất cứ điều gì cho các component dựa trên chức năng; nó chỉ invoke element.

Những gì được trả lại từ component của HelloMessage là React element mô tả một  React.Fragment Component:

React ngay bây giờ cần trả lời câu hỏi:  React.Fragment là gì?

React sẽ tiếp tục giảm các mô tả không xác định của các component cho đến khi chỉ có các DOM nodes hợp lệ. Mô tả  React.Fragment được dịch sang 2 React element, một mô tả div và còn lại mô tả một thành phần Today 

React ngay bây giờ cần trả lời câu hỏi: Today  là gì?

Nó gọi hàm Today  để đưa ra câu hỏi cuối cùng này. Hàm Today  trả về một React element mô tả một div.

Tại thời điểm này, virtual tree hoàn thành với tất cả các React elements mô tả các DOM nodes. React sử dụng thuật toán đối chiếu của nó để tìm ra những gì điều được cập nhật trong browser. Các node đã được dịch với instance component duy trì hiệu quả của việc modify instance đó.

Nguồn: TopDev via Medium.freecodecamp

Báo cáo bài viết vi phạm bản quyền>>