PureComponent
PureComponent
tương tự như Component
nhưng nó bỏ qua việc re-render khi props và state giống nhau. Các component class vẫn được React hỗ trợ, nhưng chúng tôi khuyên bạn không nên sử dụng chúng trong code mới.
class Greeting extends PureComponent {
render() {
return <h1>Xin chào, {this.props.name}!</h1>;
}
}
Tham khảo
PureComponent
Để bỏ qua việc re-render một class component khi props và state giống nhau, hãy kế thừa PureComponent
thay vì Component
:
import { PureComponent } from 'react';
class Greeting extends PureComponent {
render() {
return <h1>Xin chào, {this.props.name}!</h1>;
}
}
PureComponent
là một lớp con của Component
và hỗ trợ tất cả các API của Component
. Kế thừa PureComponent
tương đương với việc định nghĩa một phương thức shouldComponentUpdate
tùy chỉnh để so sánh nông props và state.
Cách sử dụng
Bỏ qua các re-render không cần thiết cho class component
React thường re-render một component bất cứ khi nào parent của nó re-render. Để tối ưu hóa, bạn có thể tạo một component mà React sẽ không re-render khi parent của nó re-render, miễn là các props và state mới của nó giống với các props và state cũ. Class component có thể chọn tham gia hành vi này bằng cách kế thừa PureComponent
:
class Greeting extends PureComponent {
render() {
return <h1>Xin chào, {this.props.name}!</h1>;
}
}
Một React component phải luôn có logic render thuần túy. Điều này có nghĩa là nó phải trả về cùng một đầu ra nếu props, state và context của nó không thay đổi. Bằng cách sử dụng PureComponent
, bạn đang nói với React rằng component của bạn tuân thủ yêu cầu này, vì vậy React không cần phải re-render miễn là props và state của nó không thay đổi. Tuy nhiên, component của bạn vẫn sẽ re-render nếu một context mà nó đang sử dụng thay đổi.
Trong ví dụ này, hãy để ý rằng component Greeting
re-render bất cứ khi nào name
thay đổi (vì đó là một trong các props của nó), nhưng không re-render khi address
thay đổi (vì nó không được truyền cho Greeting
dưới dạng một prop):
import { PureComponent, useState } from 'react'; class Greeting extends PureComponent { render() { console.log("Greeting was rendered at", new Date().toLocaleTimeString()); return <h3>Xin chào{this.props.name && ', '}{this.props.name}!</h3>; } } export default function MyApp() { const [name, setName] = useState(''); const [address, setAddress] = useState(''); return ( <> <label> Tên{': '} <input value={name} onChange={e => setName(e.target.value)} /> </label> <label> Địa chỉ{': '} <input value={address} onChange={e => setAddress(e.target.value)} /> </label> <Greeting name={name} /> </> ); }
Các lựa chọn thay thế
Migrate từ một class component PureComponent
sang một function
Chúng tôi khuyên bạn nên sử dụng function component thay vì class component trong code mới. Nếu bạn có một số class component hiện có đang sử dụng PureComponent
, đây là cách bạn có thể chuyển đổi chúng. Đây là code gốc:
import { PureComponent, useState } from 'react'; class Greeting extends PureComponent { render() { console.log("Greeting was rendered at", new Date().toLocaleTimeString()); return <h3>Xin chào{this.props.name && ', '}{this.props.name}!</h3>; } } export default function MyApp() { const [name, setName] = useState(''); const [address, setAddress] = useState(''); return ( <> <label> Tên{': '} <input value={name} onChange={e => setName(e.target.value)} /> </label> <label> Địa chỉ{': '} <input value={address} onChange={e => setAddress(e.target.value)} /> </label> <Greeting name={name} /> </> ); }
Khi bạn chuyển đổi component này từ một class sang một function, hãy bọc nó trong memo
:
import { memo, useState } from 'react'; const Greeting = memo(function Greeting({ name }) { console.log("Greeting was rendered at", new Date().toLocaleTimeString()); return <h3>Xin chào{name && ', '}{name}!</h3>; }); export default function MyApp() { const [name, setName] = useState(''); const [address, setAddress] = useState(''); return ( <> <label> Tên{': '} <input value={name} onChange={e => setName(e.target.value)} /> </label> <label> Địa chỉ{': '} <input value={address} onChange={e => setAddress(e.target.value)} /> </label> <Greeting name={name} /> </> ); }