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

Nâng cao hiệu suất React Hooks với React.memo, Memoization và Callback Functions

0 0 80

Người đăng: Nguyen Thanh Cong

Theo Viblo Asia

1.Ngăn Re-render và React.memo

React.memo là một chức năng cho phép tối ưu hóa cách các component được render và được sử dụng trong functional component.

Đặc biệt, nó thực hiện một quá trình được gọi là memoization giúp ngăn các component re-render khi chúng không cần làm như vậy (phần này sẽ được định nghĩa chi tiết hơn ở mục useMemo)

React.memo giúp ích nhiều nhất trong việc ngăn list các component được re-render khi các parent-component của chúng re-render.

React.memo() là một HOC (Higher-Order Components), chứ ko phải hooks. Cơ chế hoạt động giống như một Pure Component (được sử dụng nhiều với Class Component).

React.memo() sẽ chỉ render lại component nếu props thay đổi và sử dụng pattern shallow comparison ( Khi component trở nên phức tạp, có thể dùng dến một pattern khác gọi là shallow comparison sẽ so sánh tất cả các thuộc tính của props và state để quyết định xem component này có cần update hay không)

Ví dụ:

function App() { const [skill, setSkill] = React.useState('') const [skills, setSkills] = React.useState([ 'HTML', 'CSS', 'JavaScript' ]) function handleChangeInput(event) { setSkill(event.target.value); } function handleAddSkill() { setSkills(skills.concat(skill)) } return ( <> <input onChange={handleChangeInput} /> <button onClick={handleAddSkill}>Add Skill</button> <SkillList skills={skills} /> </> );
} const SkillList = React.memo(({ skills }) => { console.log('rerendering'); return ( <ul> {skills.map((skill, i) => <li key={i}>{skill}</li>)} </ul> )
}) export default App

Trong ví dụ trên, có sử dụng 2 state là 'skill' và 'skills'. Một function hiển thị list kỹ năng là "SkillList" và có thể thêm hoặc xóa skill trong danh sách.

Vấn đề ở đây là mỗi khi nhập đầu vào là 1 skill mới, state sẽ được cập nhập và component SkillList sẽ re-render liên tục và khiến cho hiệu năng bị giảm.

Tuy nhiên, khi bọc component SkillList trong React.memo (là một hàm bậc cao hơn (HOC), có nghĩa là nó chấp nhận một hàm làm đối số), nó sẽ không còn render những view không cần thiết khi parent component re-render.

2. Memoization và useMemo

Khi quá trình Memoization được thực hiện, nó sẽ tính toán và lưu kết quả cho từng bộ input và khi gặp lại bộ input đã từng thực hiện thì nó sẽ không tính toán nữa mà trả về kết quả có sẵn luôn.

useMemo rất giống useCallback và là để cải thiện hiệu suất. Nhưng thay vì dùng để gọi lại, useMemo để lưu trữ kết quả của các phép tính tốn kém tài nguyên.

useMemo cho phép chúng ta memoize , hoặc ghi nhớ kết quả của phép tính phức tạp khi phép tính đó đã được thực hiện.

useMemo trả về một giá trị từ phép tính, sau đó được lưu trữ trong một biến.

useMemo tạo ra một memoized value và chỉ tính toán ra value mới khi dependencies thay đổi. Nó nhận vào 2 tham số là function và dependencies. Nó trả về memoized value và chỉ tính toán value mới khi dependencies thay đổi. Nếu dùng empty dependencies thì không bao giờ tính toán lại value mới.

VÍ dụ:

function App() { const [skill, setSkill] = React.useState('') const [skills, setSkills] = React.useState([ 'HTML', 'CSS', 'JavaScript', ...thousands more items ]) function handleChangeInput(event) { setSkill(event.target.value); } function handleAddSkill() { setSkills(skills.concat(skill)) } const handleRemoveSkill = React.useCallback((skill) => { setSkills(skills.filter(s => s !== skill)) }, [skills]) return ( <> <SearchSkills skills={skills} /> <input onChange={handleChangeInput} /> <button onClick={handleAddSkill}>Add Skill</button> <SkillList skills={skills} handleRemoveSkill={handleRemoveSkill} /> </> );
} function SearchSkills() { const [searchTerm, setSearchTerm] = React.useState(''); const searchResults = React.useMemo(() => { return skills.filter((s) => s.includes(searchTerm); }), [searchTerm]); function handleSearchInput(event) { setSearchTerm(event.target.value); } return ( <> <input onChange={handleSearchInput} /> <ul> {searchResults.map((result, i) => <li key={i}>{result}</li> </ul> </> );
} export default App

Lấy từ ví dụ ở mục React.memo() bên trên, ta thêm vào function SearchSkills để check hiệu năng khi sử dụng useMemo

Chẳng hạn, đối với ví dụ trên sẽ có hàng nghìn skill mà chúng ta có thể tìm kiếm. Vậy làm cách nào để tìm và hiển thị một cách hiệu quả các kỹ năng phù hợp với cụm từ tìm kiếm khi người dùng nhập vào đầu vào?

Sử dụng React.useMemo để memoize (remember) giá trị trả về từ action tìm kiếm và chỉ chạy khi nó thay đổi searchTerm (state)

3.Callback functions và useCallback

useCallback là một hook được sử dụng để cải thiện hiệu suất component. Callback functions là tên của các hàm được "callback" trong một parent component.

useCallback giúp tạo ra một memoized callback và chỉ tạo ra callback mới khi dependencies thay đổi. Nó nhận vào 2 tham số là "function" và "dependencies". Nó trả về là memoized callback

useCallback chỉ tạo ra function mới khi dependencies thay đổi. Nếu dùng empty dependencies thì không bao giờ tạo ra function mới.

useCallback là chức năng theo cách tương tự như React.memo hoạt động. Nó memoize các function callback, vì vậy nó không được tạo lại trên mỗi lần render.

Ví dụ:

function SearchSkill() { const handleSearchTerm = (type) => {} return <FormMik onChange={handleSearchTerm} />; } 

Mỗi lần SearchSkill re-render sẽ tạo ra một function mới và FormMik bị re-render

function SearchSkill() { const handleSearchTerm = useCallback((type) => {}, []) return <FormMik onChange={handleSearchTerm} />; }

Mỗi lần SearchSkill re-render do có useCallback() nó chỉ tạo function một lần đầu và FormMik không bị re-render.

4. Tổng kết

  • React.memo() là một HOC, chứ ko phải hooks.
  • Memoization chính là trả về kết quả đã từng thực hiện mà không cần phải đi tính toán lại. Tiết kiệm tài nguyên, thời gian cho các xử lý tính toán nặng.
  • useCallback và useMemo là 2 phương pháp áp dụng kỹ thuật memoization rất nên được sử dụng trong react hook. Tuy nhiên nên áp dụng cho các phần render là đồ thị, biểu đồ, animation hoặc các component nặng về render như re-render kết quả trang khi search.

Cảm ơn các bạn đã theo dõi bài viết đến đây. Xin chào và hẹn gặp lại!!!

Link tham khảo: https://www.freecodecamp.org/news/react-cheatsheet-with-real-world-examples/

Bình luận

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

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

Cùng tìm hiểu về các hook trong React hooks

Đối với ai đã từng làm việc với React thì chắc hẳn đã có những lúc cảm thấy bối rối không biết nên dùng stateless (functional) component hay là stateful component. Nếu có dùng stateful component thì cũng sẽ phải loay hoay với đống LifeCycle 1 cách khổ sở Rất may là những nhà phát triển React đã kịp

0 0 100

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

Khi nào nên (và không nên) sử dụng Redux

. Công việc quản lý state với những hệ thống lớn và phức tạp là một điều khá khó khăn cho đến khi Redux xuất hiện. Lấy cảm hứng từ design pattern Flux, Redux được thiết kế để quản lý state trong các project JavaScript.

0 0 127

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

ReactJS: Props và State

Nếu bạn đã học ReactJS hay React Native, bạn sẽ thấy các Props và State được sử dụng rất nhiều. Vậy chính xác chúng là gì? Làm thế nào để chúng ta sử dụng chúng đúng mục đích đây.

0 0 59

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

State và Props trong Reactjs

Hello các bạn, tiếp tục seri tìm hiểu về ReactJs hôm nay mình xin giới thiệu đến các bạn hai thứ mình cho là thú vị nhất của ReactJs là State và Props. State bạn có thể hiểu đơn giản là một nơi mà bạn lưu trữ dữ liệu của Component, từ đó bạn có thể luân chuyển dữ liệu đến các thành phần trong Compon

0 0 54

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

Memoization trong React

. 1.Introduction. Memoization có liên quan mật thiết đến bộ nhớ đệm, và dưới đây là một ví dụ đơn giản:. const cache = {}.

0 0 51

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

CI-CD Lab - Sử dụng Jenkins, Nginx deploy dự án ReactJS (UmiJS) lên AWS EC2

1. Lập trình viên không nên chỉ biết code. Lập trình viên phải biết sửa máy giặt, sửa điện, sửa ống nước, có người yêu ,.... và phải biết triển khai code lên internet. Khi đã biết triển khai code lên internet (được sếp đánh giá rất cao rồi ) thì lại phải học tiếp CI - CD để build và test code tự độn

0 0 259