ReactJS: Cách gỡ lỗi (debug) các component bằng React Developer Tools
Giới thiệu
Vì các ứng dụng React được tạo ra để mở rộng quy mô và phát triển nhanh chóng, nên rất dễ dàng để các lỗi tinh vi xâm nhập vào mã của bạn. Extension React Developer Tools có thể giúp bạn theo dõi những lỗi bằng cách cho bạn cái nhìn sâu sắc hơn vào state hiện tại của mỗi component. React Developer Tools cung cấp cho bạn một giao diện để khám phá cây component React cùng với các prop, state và ngữ cảnh hiện tại cho các component riêng lẻ. React Developer Tools cũng cho phép bạn xác định component nào đang hiển thị lại và có thể tạo biểu đồ để hiển thị thời gian các component riêng lẻ cần hiển thị. Bạn có thể sử dụng thông tin này để theo dõi mã không hiệu quả hoặc để tối ưu hóa các component chứa nhiều dữ liệu.
Bài hướng dẫn này bắt đầu bằng cách cài đặt tiện ích mở rộng trình duyệt React Developer Tools. Sau đó, ta sẽ xây dựng một trình phân tích văn bản như một ứng dụng thử nghiệm, sẽ lấy một khối văn bản và hiển thị thông tin như số từ, số ký tự và cách sử dụng ký tự. Cuối cùng, bạn sẽ sử dụng React Developer Tools để khám phá các component của trình phân tích văn bản và theo dõi các prop và ngữ cảnh thay đổi. Các ví dụ sẽ sử dụng trình duyệt Chrome, nhưng bạn cũng có thể sử dụng plugin cho Firefox.
Đến cuối hướng dẫn này, bạn sẽ có thể bắt đầu sử dụng React Developer Tools để gỡ lỗi và khám phá bất kỳ dự án React nào.
Điều kiện tiên quyết
- Để sử dụng tiện ích mở rộng Công cụ dành cho nhà phát triển Chrome React, bạn sẽ cần tải xuống và cài đặt trình duyệt web Google Chrome hoặc trình duyệt web Chromium mã nguồn mở. Bạn cũng có thể theo dõi bằng cách sử dụng plugin FireFox của React Developer Tools cho trình duyệt web FireFox.
- Bạn sẽ cần một môi trường phát triển chạy Node.js.
- Môi trường phát triển React được thiết lập với Create React App. Hướng dẫn này sẽ sử dụng
debug-tutorial
làm tên dự án. - Bạn sẽ sử dụng các thành phần React và Hook trong hướng dẫn này, bao gồm Hook
useState
và ngữ cảnh. Bạn có thể tìm hiểu về các thành phần và Hook trong hướng dẫn của chúng tôi Cách tạo các component tùy chỉnh trong React, Cách quản lý state với Hook trên các component React và Cách chia sẻ state trên các component React với ngữ cảnh. - Bạn cũng sẽ cần kiến thức cơ bản về JavaScript và HTML. Kiến thức cơ bản về CSS cũng sẽ hữu ích.
Bước 1 - Tạo một dự án trống
Trong bước này, bạn sẽ tạo một dự án mới bằng Create React App. Sau đó, bạn sẽ xóa dự án mẫu và các tệp liên quan được cài đặt khi bạn khởi động dự án. Cuối cùng, bạn sẽ tạo một cấu trúc tệp đơn giản để tổ chức các component của mình. Điều này sẽ cung cấp cho bạn một cơ sở vững chắc để xây dựng ứng dụng mẫu của hướng dẫn này để tạo style trong bước tiếp theo.
Để bắt đầu, hãy thực hiện một dự án mới. Bạn mở terminal và chạy tập lệnh sau để cài đặt một dự án mới bằng cách sử dụng create-react-app
:
npx create-react-app context-tutorial
Sau khi dự án kết thúc, hãy thay đổi vào thư mục:
cd context-tutorial
Khởi động dự án với lệnh:
npm start
http://localhost:3000/
. Nếu bạn đang chạy điều này từ một máy chủ từ xa, địa chỉ sẽ là .http://your_domain:3000
Trình duyệt của bạn sẽ tải với một ứng dụng React đơn giản được bao gồm như một phần của Create React App:
Bạn sẽ xây dựng một tập hợp các component tùy chỉnh hoàn toàn mới, vì vậy bạn sẽ cần bắt đầu bằng cách xóa một số mã soạn sẵn để bạn có thể có một dự án trống.
Để bắt đầu, hãy mở component src/App.js
. Đây là component gốc được đưa vào trang. Tất cả các component sẽ bắt đầu từ đây. Bạn sửa lại file để trong đó chỉ còn chứa như sau:
import './App.css';
function App() {
return <></>;
}
export default App;
Mở một terminal khác và thực hiện thao tác xóa file logo.svg:
rm src/logo.svg
Tạo thư mục components:
mkdir src/components
Tạo thư mục App:
mkdir src/components/App
Di chuyển các file App.* vào thư mục App:
mv src/App.* src/components/App
Mở file index.js và chỉnh sửa:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App/App';
import * as serviceWorker from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
Lưu file lại và quay lại trang web ta được một trang web trống.
Bây giờ bạn đã hoàn thành dự án Tạo ứng dụng React mẫu, hãy tạo một cấu trúc tệp đơn giản. Điều này sẽ giúp bạn giữ cho các component của bạn cô lập và độc lập.
Tạo một thư mục được gọi components
trong thư mục src
, components sẽ là nơi chứa tất cả các component tùy chỉnh của bạn.
Bước 2 - Cài đặt Tiện ích mở rộng React Developer Tools
Trong bước này, bạn sẽ cài đặt tiện ích mở rộng trình duyệt React Developer Tools trong Chrome. Bạn sẽ sử dụng các công cụ dành cho nhà phát triển trong JavaScript console của Chrome để khám phá cây component của dự án debug-tutorial
đã thực hiện trong Bước 1. Bước này sẽ sử dụng Chrome, nhưng các bước sẽ gần giống nhau để cài đặt React Developer Tools dưới dạng tiện ích bổ sung trong Firefox.
Đến cuối bước này, bạn sẽ cài đặt React Developer Tools trong trình duyệt của mình và bạn sẽ có thể khám phá và lọc các component theo tên.
React Developer Tools là một plugin dành cho trình duyệt Chrome và Firefox. Khi bạn thêm tiện ích mở rộng, bạn đang thêm các công cụ bổ sung vào bảng điều khiển dành cho nhà phát triển. Truy cập trang plugin của Chrome dành cho React Developer Tools để cài đặt tiện ích mở rộng.
Nhấp vào nút Add to Chrome. Sau đó nhấp vào nút Add extension để xác nhận:
Chrome sẽ cài đặt tiện ích mở rộng và một thông báo thành công và một biểu tượng mới sẽ xuất hiện ở góc trên bên phải của trình duyệt bên cạnh thanh địa chỉ:
Nếu biểu tượng không xuất hiện, bạn có thể thêm nó bằng cách nhấp vào biểu tượng mảnh ghép, sau đó nhấp vào biểu tượng đinh ghim để ghim lại React Developer Tools:
Khi bạn đang ở trên một trang không có bất kỳ component React nào, biểu tượng sẽ xuất hiện màu xám. Tuy nhiên, nếu bạn đang ở trang có các component React, biểu tượng sẽ xuất hiện màu xanh lam và xanh lục. Nếu bạn nhấp vào biểu tượng, nó sẽ cho biết rằng ứng dụng đang chạy phiên bản production của React.
Truy cập trang reactjs.org
để biết rằng trang chủ đang chạy phiên bản production của React:
Bây giờ bạn đang ở trên một trang web sử dụng React, hãy mở bảng điều khiển để truy cập Công cụ dành cho nhà phát triển React. Mở bảng điều khiển bằng cách nhấp chuột phải và kiểm tra một phần tử hoặc dùng phím F12 hoặc bằng cách mở thanh công cụ bằng cách nhấp vào View> Developer> Console.
Khi bạn mở console, bạn sẽ thấy hai tab mới: Components và Profiler:
Tab Components sẽ hiển thị cây component React hiện tại, cùng với các prop, state, hoặc ngữ cảnh. Tab Profiler cho phép bạn ghi lại các tương tác và kết xuất component. Bạn sẽ khám phá tab Profiler trong Bước 4.
Bấm vào tab Component để xem cây component hiện tại.
Vì đây là bản dựng production, mã sẽ được rút gọn và các component sẽ không có tên mô tả:
Bây giờ bạn đã dùng thử React Developer Tools trên một trang web đang hoạt động, bạn có thể sử dụng nó trên ứng dụng thử nghiệm của mình. Nếu bạn chưa khởi động ứng dụng debug-tutorial
của mình, hãy chuyển đến cửa sổ đầu cuối và chạy npm start
từ thư mục gốc của dự án.
Mở trình duyệt tới địa chỉ http://localhost:3000.
Lưu ý rằng biểu tượng của React Developer Tools hiện có màu đỏ và trắng. Nếu bạn nhấp vào biểu tượng React Developer Tools, bạn sẽ thấy cảnh báo rằng trang đang ở chế độ development.
Mở console và bạn sẽ tìm thấy tên của component App
trong tab Component.
Vẫn chưa có nhiều thông tin, nhưng khi bạn xây dựng dự án ở bước tiếp theo, bạn sẽ thấy tất cả các component của mình tạo thành một cây có thể điều hướng.
Trong bước này, bạn đã thêm tiện ích mở rộng React Developer Tools vào Chrome. Bạn đã kích hoạt các công cụ trên cả trang production và trang development, đồng thời bạn đã khám phá nhanh dự án debug-tutorial
của mình trong tab Component. Trong bước tiếp theo, bạn sẽ xây dựng app trình phân tích văn bản mà bạn sẽ sử dụng để thử các tính năng của React Developer Tools.
Bước 3 - Xác định ngữ cảnh và các prop component thời gian thực
Trong bước này, bạn sẽ xây dựng một ứng dụng nhỏ để phân tích một khối văn bản. Ứng dụng sẽ xác định và báo cáo số từ, số ký tự và tần suất ký tự của văn bản trong trường input. Khi xây dựng ứng dụng, bạn sẽ sử dụng React Developer Tools để khám phá state hiện tại và các prop của từng component. Bạn cũng sẽ sử dụng React Developer Tools để xem ngữ cảnh hiện tại trong các component được lồng sâu vào nhau. Cuối cùng, bạn sẽ sử dụng các công cụ để xác định các component hiển thị lại dưới dạng thay đổi state.
Đến cuối bước này, bạn sẽ có thể sử dụng React Developer Tools để khám phá một ứng dụng đang hoạt động và quan sát state và prop hiện tại mà không cần câu lệnh console hoặc trình gỡ lỗi.
Để bắt đầu, bạn sẽ tạo một component đầu vào sẽ chiếm một lượng lớn văn bản.
Mở file App.js
ra, thêm một phần tử div
với một lớp wrapper
, sau đó tạo một phần tử <label> bao quanh một phần tử <textarea>:
import './App.css';
function App() {
return(
<div className="wrapper">
<label htmlFor="text">
Add Your Text Here:
<br/>
<br/>
<textarea
id="text"
name="text"
rows="10"
cols="100"
>
</textarea>
</label>
</div>
)
}
export default App;
Đây sẽ là khu vực đầu vào cho người dùng của bạn. Thuộc tính htmlFor
liên kết phần tử label
với textarea qua id
sử dụng JSX. Bạn cũng cung cấp cho <textarea>
10 hàng và 100 cột để cung cấp chỗ cho một lượng lớn văn bản.
Lưu fle lại. Tiếp theo, mở App.css
ra, thêm một số style sau vào ứng dụng:
.wrapper {
padding: 20px;
}
.wrapper button {
background: none;
border: black solid 1px;
cursor: pointer;
margin-right: 10px;
}
.wrapper div {
margin: 20px 0;
}
Ở đây, bạn thêm một số phần đệm vào class wrapper
, sau đó đơn giản hóa <button>
bằng cách loại bỏ màu nền và thêm một số lề. Cuối cùng, bạn thêm một lề nhỏ cho <div>
. Các style này sẽ áp dụng cho các component bạn sẽ xây dựng để hiển thị thông tin về văn bản.
Lưu file lại và quay lại trang web ta sẽ được kết quả như sau:
Mở file App.js
ra. Tiếp theo, tạo một ngữ cảnh để giữ giá trị trong phần tử <textarea>
. Chụp lại dữ liệu bằng Hook useState:
import { createContext, useState } from 'react'; import './App.css'; export const TextContext = createContext(); function App() { const [text, setText] = useState(''); return( <TextContext.Provider value={text}> <div className="wrapper"> <label htmlFor="text"> Add Your Text Here: <br/>
<br/> <textarea id="text" name="text" rows="10" cols="100" onChange={e => setText(e.target.value)} > </textarea> </label> </div> </TextContext.Provider> ) } export default App;
Trong đoạn code trên, trước tiên export TextContext
, sau đó bọc toàn bộ component bằng TextContext.Provider
. Bắt dữ liệu bằng cách thêm một prop onChange
vào <textarea>
.
Lưu file lại sau đó quay lại trang web. Đảm bảo rằng bạn đã mở React Developer Tools và bạn sẽ thấy component App
bây giờ hiển thị Context.Provider
dưới dạng component con.
Component theo mặc định có tên chung— Context
—nhưng bạn có thể thay đổi tên đó bằng cách thêm thuộc tính displayName
vào ngữ cảnh đã tạo. Bên trong App.js
, thêm một dòng nơi bạn thiết lập displayName
thành TextContext
:
import React, { createContext, useState } from 'react';
import './App.css';
export const TextContext = createContext();
TextContext.displayName = 'TextContext';
function App() {
...
}
export default App;
Không cần thiết phải thêm một displayName
, nhưng nó sẽ giúp điều hướng các component khi phân tích cây component trong console. Bạn cũng sẽ thấy giá trị của Hook useState
trong thanh bên. Nhập vào một số văn bản và bạn sẽ thấy giá trị được cập nhật trong React Developer Tools bên dưới phần hooks trên component App
.
Như bạn thấy ở đây Hook cũng có tên chung là State
, nhưng điều này không dễ cập nhật như ngữ cảnh. Có một Hook là useDebugValue
, nhưng nó chỉ hoạt động trên Hook tùy chỉnh và không được khuyến nghị cho tất cả các Hook tùy chỉnh.
Trong trường hợp này, state cho component App
là chỗ dựa TextContext.Provider
. Nhấp vào TextContext.Provider
trong React Developer Tools và bạn sẽ thấy rằng prop value
cũng phản ánh giá trị đầu vào mà bạn đã thiết lập với state:
React Developer Tools đang hiển thị cho bạn thông tin ngữ cảnh và hỗ trợ thời gian thực, đồng thời giá trị sẽ tăng lên khi bạn thêm các component.
Tiếp theo, thêm một component được gọi là TextInformation
. Component này sẽ là nơi chứa các component có phân tích dữ liệu cụ thể, chẳng hạn như số lượng từ.
Đầu tiên, hãy tạo thư mục:
mkdir src/components/TextInformation
Sau đó tạo và mở TextInformation.js
ra. Bên trong component này bạn sẽ có ba component con riêng biệt: CharacterCount
, WordCount
, và CharacterMap
.
Component TextInformation
sẽ sử dụng Hook useReducer
để chuyển đổi hiển thị của từng component. Tạo một hàm reducer
chuyển đổi giá trị hiển thị của từng component và một nút để chuyển đổi từng component bằng một hành động onClick
:
import React, { useReducer } from 'react';
const reducer = (state, action) => {
return {
...state,
[action]: !state[action]
}
}
export default function TextInformation() {
const [tabs, toggleTabs] = useReducer(reducer, {
characterCount: true,
wordCount: true,
characterMap: true
});
return(
<div>
<button onClick={() => toggleTabs('characterCount')}>Character Count</button>
<button onClick={() => toggleTabs('wordCount')}>Word Count</button>
<button onClick={() => toggleTabs('characterMap')}>Character Map</button>
</div>
)
}
Lưu ý rằng Hook useReducer
của bạn bắt đầu bằng một đối tượng trong đó các thuộc tính bắt đầu bằng true. Hàm reducer sử dụng toán tử spread để bảo toàn giá trị trước đó trong khi thiết lập giá trị mới bằng cách sử dụng tham số action
.
Lưu file lại. Sau đó mở App.js
ra và thêm component đã tạo vào:
import React, { createContext, useState } from 'react';
import './App.css';
import TextInformation from '../TextInformation/TextInformation';
...
function App() {
const [text, setText] = useState('');
return(
<TextContext.Provider value={text}>
<div className="wrapper">
<label htmlFor="text">
Add Your Text Here:
<br/>
<br/>
<textarea
id="text"
name="text"
rows="10"
cols="100"
onChange={e => setText(e.target.value)}
>
</textarea>
</label>
<TextInformation />
</div>
</TextContext.Provider>
)
}
export default App;
Lưu file lại và quay lại trang web bạn sẽ thấy component được cập nhật. Nếu bạn nhấp vào TextInformation
trong React Developer Tools, bạn sẽ thấy có sự cập nhật giá trị trên mỗi lần nhấp vào nút:
Bây giờ bạn đã có component wrapper, bạn sẽ cần tạo từng component thông tin. Mỗi component sẽ nhận một prop được gọi show
. Nếu show
là false thì component sẽ trả về null
. Các component sẽ sử dụng TextContext
, phân tích dữ liệu và hiển thị kết quả.
Để bắt đầu, hãy tạo component CharacterCount
.
Đầu tiên, tạo một thư mục mới:
mkdir src/components/CharacterCount
Sau đó, mở CharacterCount.js
ra và tạo một hàm sử dụng prop show
và hiển thị null
nếu show
là false:
import { useContext } from 'react';
import PropTypes from 'prop-types';
import { TextContext } from '../App/App';
export default function CharacterCount({ show }) {
const text = useContext(TextContext);
if(!show) {
return null;
}
return(
<div>
Character Count: {text.length}
</div>
)
}
CharacterCount.proTypes = {
show: PropTypes.bool.isRequired
}
Ở đoạn code trên, bên trong hàm CharacterCount
bạn chỉ định giá trị của TextContext
cho một biến bằng cách sử dụng Hook useContext
. Sau đó, bạn trả về một <div>
để hiển thị số ký tự bằng cách dùng thuộc tính length
. Cuối cùng, PropTypes thêm một hệ thống kiểu để cung cấp một số thực thi để đảm bảo không sai kiểu.
Lưu file lại. Mở TextInformation.js
ra và import CharacterCount
và thêm component sau các nút, truyền tabs.characterCount
dưới dạng prop show
:
import { useReducer } from 'react';
import CharacterCount from '../CharacterCount/CharacterCount';
const reducer = (state, action) => {
return {
...state,
[action]: !state[action]
}
}
export default function TextInformation() {
const [tabs, toggleTabs] = useReducer(reducer, {
characterCount: true,
wordCount: true,
characterMap: true
});
return(
<div>
<button onClick={() => toggleTabs('characterCount')}>Character Count</button>
<button onClick={() => toggleTabs('wordCount')}>Word Count</button>
<button onClick={() => toggleTabs('characterMap')}>Character Map</button>
<CharacterCount show={tabs.characterCount} />
</div>
)
}
Lưu file lại và quay lại trang web bạn sẽ thấy component trong React Developer Tools. Lưu ý rằng khi bạn đưa thêm từ vào textarea, ngữ cảnh sẽ cập nhật. Nếu bạn chuyển đổi component, bạn sẽ thấy các prop cập nhật sau mỗi lần nhấp. Nếu bạn nhấn và nhấn vào nút Character Count thì component CharacterCount
sẽ ẩn hiện:
Bạn cũng có thể thêm hoặc thay đổi prop theo cách thủ công bằng cách nhấp vào thuộc tính và cập nhật giá trị:
Tiếp theo ta tạo component WordCount
.
Tạo thư mục:
mkdir src/components/WordCount
Tạo và mở WordCount.js ra. Component này nói chung tương tự với CharacterCount
, nhưng sử dụng phương thức split dựa trên dấu cách để tạo một mảng các từ trước khi hiển thị độ dài:
import { useContext } from 'react';
import PropTypes from 'prop-types';
import { TextContext } from '../App/App';
export default function WordCount({ show }) {
const text = useContext(TextContext);
if(!show) {
return null;
}
return(
<div>
Word Count: {text.split(' ').length}
</div>
)
}
WordCount.proTypes = {
show: PropTypes.bool.isRequired
}
Lưu file lại.
Cuối cùng ta tạo component CharacterMap
. Component này sẽ hiển thị tần suất một ký tự cụ thể được sử dụng trong một khối văn bản. Sau đó, nó sẽ sắp xếp các ký tự theo tần suất trong đoạn văn và hiển thị kết quả.
Đầu tiên, hãy tạo thư mục:
mkdir src/components/CharacterMap
Tạo file CharacterMap.js và mở ra, import và sử dụng component TextContext
và sử dụng prop show
để hiển thị kết quả như bạn đã làm trong các component trước:
import { useContext } from 'react';
import PropTypes from 'prop-types';
import { TextContext } from '../App/App';
export default function CharacterMap({ show }) {
const text = useContext(TextContext);
if(!show) {
return null;
}
return(
<div>
Character Map: {text.length}
</div>
)
}
CharacterMap.proTypes = {
show: PropTypes.bool.isRequired
}
Component này sẽ cần một hàm phức tạp hơn một chút để tạo bản đồ tần tần suất cho mỗi chữ cái. Bạn sẽ cần phải xem qua từng ký tự và tăng một giá trị bất cứ khi nào có lặp lại. Sau đó, bạn sẽ cần lấy dữ liệu đó và sắp xếp nó sao cho các chữ cái thường gặp nhất nằm ở đầu danh sách.
Để thực hiện việc này, hãy thêm mã được đánh dấu sau:
import { useContext } from 'react';
import PropTypes from 'prop-types';
import { TextContext } from '../App/App';
function itemize(text){
const letters = text.split('')
.filter(l => l !== ' ')
.reduce((collection, item) => {
const letter = item.toLowerCase();
return {
...collection,
[letter]: (collection[letter] || 0) + 1
}
}, {})
return Object.entries(letters)
.sort((a, b) => b[1] - a[1]);
}
export default function CharacterMap({ show }) {
const text = useContext(TextContext);
if(!show) {
return null;
}
return(
<div>
Character Map:
{itemize(text).map(character => (
<div key={character[0]}>
{character[0]}: {character[1]}
</div>
))}
</div>
)
}
CharacterMap.proTypes = {
show: PropTypes.bool.isRequired
}
Trong đoạn code trên, bạn tạo một hàm được gọi là itemize
có nhiệm vụ tách văn bản trong textarea thành một mảng ký tự bằng cách sử dụng phương thức split()
. Sau đó, bạn reduce
mảng thành một đối tượng bằng cách thêm ký tự và sau đó tăng số lượng cho mỗi ký tự tiếp theo. Cuối cùng, bạn chuyển đổi đối tượng thành một mảng các cặp bằng cách sử dụng Object.entries
và sort để đặt các ký tự được sử dụng nhiều nhất ở trên cùng.
Sau khi bạn tạo hàm, bạn truyền văn bản cho hàm trong phương thức render
và map
qua kết quả để hiển thị ký tự — giá trị mảng [0]
— và số đếm — giá trị mảng — [1]
bên trong thẻ <div>
.
Lưu file lại. Hàm này sẽ cho bạn cơ hội khám phá một số tính năng hoạt động của React Developer Tools trong phần tiếp theo.
Tiếp theo, thêm các component mới vào TextInformation
và xem kết quả trong React Developer Tools.
Mở TextInformation.js
ra, sau đó import and kết xuất các component mới:
import { useReducer } from 'react';
import CharacterCount from '../CharacterCount/CharacterCount';
import CharacterMap from '../CharacterMap/CharacterMap';
import WordCount from '../WordCount/WordCount';
const reducer = (state, action) => {
return {
...state,
[action]: !state[action]
}
}
export default function TextInformation() {
const [tabs, toggleTabs] = useReducer(reducer, {
characterCount: true,
wordCount: true,
characterMap: true
});
return(
<div>
<button onClick={() => toggleTabs('characterCount')}>Character Count</button>
<button onClick={() => toggleTabs('wordCount')}>Word Count</button>
<button onClick={() => toggleTabs('characterMap')}>Character Map</button>
<CharacterCount show={tabs.characterCount} />
<WordCount show={tabs.wordCount} />
<CharacterMap show={tabs.characterMap} />
</div>
)
}
Lưu file lại và quay lại trang web và nếu bạn điền dữ liệu vào textarea thì bạn sẽ tìm thấy phân tích tần suất ký tự trong các component mới:
Như vậy trong phần này, bạn đã sử dụng React Developer Tools để khám phá cây component. Bạn cũng đã học cách xem các prop theo thời gian thực cho từng component và cách thay đổi các prop theo cách thủ công bằng các công cụ dành cho nhà phát triển. Cuối cùng, bạn đã xem ngữ cảnh cho sự thay đổi component với dữ liệu đưa vào.
Trong phần tiếp theo, bạn sẽ sử dụng tab Profiler của React Developer Tools để xác định component mà từ lâu đã được kết xuất từ lâu.
Bước 4 - Theo dõi kết xuất component qua các lần tương tác
Trong bước này, bạn sẽ sử dụng trình biên dịch React Developer Tools để theo dõi việc hiển thị và kết xuất component khi bạn sử dụng ứng dụng mẫu. Bạn sẽ điều hướng các flamegraphs hoặc hình ảnh trực quan về các chỉ số tối ưu hóa có liên quan của ứng dụng và sử dụng thông tin để xác định các component không hiệu quả, giảm thời gian hiển thị và tăng tốc độ ứng dụng.
Đến cuối bước này, bạn sẽ biết cách xác định các component hiển thị trong quá trình tương tác của người dùng và cách sắp xếp các component để giảm kết xuất không hiệu quả.
Một cách nhanh chóng để xem các component thay đổi lẫn nhau như thế nào là bật tính năng đánh dấu khi một component được hiển thị lại. Điều này sẽ cung cấp cho bạn một cái nhìn tổng quan trực quan về cách các component phản ứng với việc thay đổi dữ liệu.
Trong React Developer Tools, nhấp vào biểu tượng Settings. Nó sẽ giống như một bánh răng:
Sau đó tick vào check box bên dưới General có nội dung Highlight updates when components render.
Khi bạn thực hiện bất kỳ thay đổi nào, React Developer Tools sẽ đánh dấu các component hiển thị lại. Ví dụ: khi bạn thay điền dữ liệu vào textarea thì mọi component hiển thị lại vì dữ liệu được lưu trữ trên Hook ở cấp gốc và mọi thay đổi sẽ hiển thị lại toàn bộ cây component.
Lưu ý điểm nổi bật xung quanh các component, bao gồm cả phần trên cùng của màn hình xung quanh component gốc:
So sánh điều đó với cách các component hiển thị lại khi bạn nhấp vào một trong các nút để chuyển đổi dữ liệu. Nếu bạn nhấp vào một trong các nút, các component bên dưới TextInformation
sẽ hiển thị lại, nhưng không có component gốc:
Việc hiển thị các kết xuất sẽ giúp bạn nhanh chóng biết được các component có liên quan như thế nào, nhưng nó không cung cấp cho bạn nhiều dữ liệu để phân tích các component cụ thể. Để có thêm thông tin chi tiết, chúng ta hãy xem xét các công cụ của trình biên dịch.
Các công cụ cấu hình được thiết kế để giúp bạn đo lường chính xác thời gian mỗi component cần để hiển thị. Điều này có thể giúp bạn xác định các component có thể chậm hoặc xử lý mạnh.
Mở lại cài đặt và bỏ chọn hộp Highlight updates when components render. Sau đó click vào tab Profiler trong console.
Để sử dụng trình cấu hình, hãy nhấp vào vòng tròn màu xanh lam ở bên trái màn hình để bắt đầu ghi và nhấp lại vào nó khi bạn hoàn tất:
Khi dừng ghi, bạn sẽ tìm thấy biểu đồ về các thay đổi của component bao gồm thời gian hiển thị từng mục.
Để hiểu rõ về hiệu quả tương đối của các component, bạn hãy mở trang Wikipedia dành cho Creative Commons ra, copy một đoạn văn bản và dán vào textarea. Văn bản này đủ dài để cho kết quả thú vị, nhưng không quá lớn đến mức làm hỏng ứng dụng.
Sau khi dán vào văn bản, hãy thực hiện một thay đổi nhỏ đối với đầu vào. Dừng cấu hình sau khi component hoàn thành kết xuất. Sẽ có một khoảng thời gian tạm dừng dài vì ứng dụng đang xử lý quá trình kết xuất dài:
Khi bạn kết thúc quá trình ghi, React Developer Tools sẽ tạo một bản ghi hiển thị mọi component được hiển thị lại và mất bao lâu để hiển thị lại từng component.
Trong trường hợp này, mỗi khi đánh vào một ký tự của từ "Change" thì đều gây ra kết xuất lại. Quan trọng hơn, nó cho biết mỗi lần hiển thị mất bao lâu và tại sao lại có độ trễ lâu. Các component App
, TextContext.Provider
và TextInformation
mất khoảng 0,2 mili giây để rerender. Nhưng component CharacterMap
này mất khoảng 1 giây cho mỗi lần nhấn phím để hiển thị lại do phân tích cú pháp dữ liệu phức tạp trong hàm itemize
.
Trong màn hình, mỗi thanh màu vàng là một tổ hợp phím mới. Bạn có thể phát lại trình tự lần lượt bằng cách nhấp vào từng thanh. Lưu ý rằng có một chút thay đổi trong thời gian hiển thị, nhưng CharacterMap
luôn chậm:
Bạn có thể lấy thêm thông tin bằng cách chọn tùy chọn Record why each component rendered while profiling. tại mục Profiler nằm trong phần Settings (hình bánh răng) của tab Profiler.
Hãy thử chuyển đổi component Word Count và để ý xem các thay đổi diễn ra trong bao lâu. Ứng dụng vẫn bị lag mặc dù bạn không thay đổi nội dung văn bản:
Bây giờ khi bạn di con trỏ qua một component, bạn sẽ thấy rằng nó sẽ xuất hiện một lý do (hiện chú thích) khiến component đó được hiển thị lại. Trong trường hợp này, lý do component thay đổi là The parent component rendered. Đó là một vấn đề đối với component CharacterMap
. CharacterMap
đang thực hiện một phép tính tốn kém mỗi khi component cha thay đổi thay đổi, ngay cả khi prop và ngữ cảnh không thay đổi. Đó là, nó đang tính toán lại dữ liệu mặc dù dữ liệu giống hệt với lần hiển thị trước đó.
Nhấp vào tab Ranked và bạn sẽ thấy mất bao nhiêu thời gian cho CharacterMap
khi so sánh với tất cả các component khác:
React Developer Tools đã giúp cô lập một vấn đề: component CharacterMap
hiển thị lại và thực hiện một phép tính tốn kém bất cứ lúc nào khi component cha thay đổi.
Có nhiều cách để giải quyết vấn đề, nhưng tất cả chúng đều liên quan đến một số loại bộ nhớ đệm thông qua memoization, một quá trình mà dữ liệu đã được tính toán được ghi nhớ thay vì được tính toán lại. Bạn có thể sử dụng một thư viện như lodash/memoize hoặc memoize-one để lưu kết quả của hàm itemize
hoặc bạn có thể sử dụng hàm React memo
tích hợp sẵn để ghi nhớ toàn bộ component.
Nếu bạn sử dụng React memo
, hàm sẽ chỉ hiển thị lại nếu prop hoặc ngữ cảnh thay đổi. Trong trường hợp này, bạn sẽ sử dụng React memo
. Nói chung, bạn nên ghi nhớ chính dữ liệu trước vì đây là một trường hợp cá biệt hơn, nhưng có một số thay đổi thú vị trong React Developer Tools nếu bạn ghi nhớ toàn bộ component, vì vậy bạn sẽ sử dụng cách tiếp cận đó trong hướng dẫn này.
Mở CharacterMap.js
ra, import memo
từ React, sau đó truyền toàn bộ hàm vào hàm memo
:
import { memo, useContext } from 'react';
import PropTypes from 'prop-types';
import { TextContext } from '../App/App';
...
function CharacterMap({ show }) {
const text = useContext(TextContext);
if(!show) {
return null;
}
return(
<div>
Character Map:
{itemize(text).map(character => (
<div key={character[0]}>
{character[0]}: {character[1]}
</div>
))}
</div>
)
}
CharacterMap.proTypes = {
show: PropTypes.bool.isRequired
}
export default memo(CharacterMap);
Tron đoạn code trên, bạn di chuyển dòng export default
xuống cuối component sang memo
trước khi xuất. Sau đó, React sẽ so sánh các prop trước khi kết xuất lại.
Lưu file lại và quay lại trang web, khi bạn chuyển đổi WordCount
, component sẽ cập nhật nhanh hơn nhiều. Lần này, CharacterMap
không kết xuất lại. Thay vào đó, trong React Developer Tools bạn sẽ thấy một hình chữ nhật màu xám cho thấy việc hiển thị đã bị ngăn cản.
Nếu bạn nhìn vào tab Ranked, bạn sẽ thấy rằng cả biểu tượng CharacterCount
và biểu tượng WordCount
đều được kết xuất lại, nhưng vì những lý do khác nhau. Vì CharacterCount
không được ghi nhớ, nó được kết xuất lại do phần tử gốc đã thay đổi. Còn WordCount
được kết xuất lại vì các prop đã thay đổi. Ngay cả khi nó được bọc trong memo
, nó vẫn sẽ hiển thị.
Lưu ý:
memo
rất hữu ích, nhưng bạn chỉ nên sử dụng nó khi bạn gặp vấn đề về hiệu suất rõ ràng như trong trường hợp trên. Nếu không, nó có thể tạo ra một vấn đề về hiệu suất: React sẽ phải kiểm tra các prop mỗi khi nó hiển thị lại, điều này có thể gây ra sự chậm trễ trên các component nhỏ hơn.
Như vậy trong bước này, bạn đã sử dụng Profiler để xác định kết xuất lại và các component không kết xuất. Bạn cũng đã sử dụng đồ thị và đồ thị được xếp hạng để xác định các component kết xuất chậm và sau đó sử dụng hàm memo
để ngăn kết xuất lại khi không có sự thay đổi nào đối với prop hoặc ngữ cảnh.
Phần kết luận
Tiện ích mở rộng trình duyệt React Developer Tools cung cấp cho bạn một bộ tiện ích mạnh mẽ để khám phá các component của bạn trong các ứng dụng của chúng. Với những công cụ này, bạn sẽ có thể khám phá state của một component và xác định lỗi bằng cách sử dụng dữ liệu thực mà không cần câu lệnh console hoặc trình gỡ lỗi. Bạn cũng có thể sử dụng Profiler để khám phá cách các component tương tác với nhau, cho phép bạn xác định và tối ưu hóa các component có kết xuất chậm trong ứng dụng đầy đủ của bạn. Những công cụ này là một phần quan trọng của quá trình phát triển và cho bạn cơ hội khám phá các component như một phần của ứng dụng chứ không chỉ như mã tĩnh.