createContext
createContext
cho phép bạn tạo một context mà các component có thể cung cấp hoặc đọc.
const SomeContext = createContext(defaultValue)
Tham khảo
createContext(defaultValue)
Gọi createContext
bên ngoài bất kỳ component nào để tạo một context.
import { createContext } from 'react';
const ThemeContext = createContext('light');
Tham số
defaultValue
: Giá trị mà bạn muốn context có khi không có context provider phù hợp nào trong cây phía trên component đọc context. Nếu bạn không có bất kỳ giá trị mặc định có ý nghĩa nào, hãy chỉ địnhnull
. Giá trị mặc định được dùng như một phương sách cuối cùng. Nó là tĩnh và không bao giờ thay đổi theo thời gian.
Giá trị trả về
createContext
trả về một đối tượng context.
Bản thân đối tượng context không chứa bất kỳ thông tin nào. Nó đại diện cho context nào mà các component khác đọc hoặc cung cấp. Thông thường, bạn sẽ sử dụng SomeContext.Provider
trong các component phía trên để chỉ định giá trị context và gọi useContext(SomeContext)
trong các component phía dưới để đọc nó. Đối tượng context có một vài thuộc tính:
SomeContext.Provider
cho phép bạn cung cấp giá trị context cho các component.SomeContext.Consumer
là một cách thay thế và hiếm khi được sử dụng để đọc giá trị context.
SomeContext.Provider
Bọc các component của bạn vào một context provider để chỉ định giá trị của context này cho tất cả các component bên trong:
function App() {
const [theme, setTheme] = useState('light');
// ...
return (
<ThemeContext.Provider value={theme}>
<Page />
</ThemeContext.Provider>
);
}
Props
value
: Giá trị mà bạn muốn truyền cho tất cả các component đọc context này bên trong provider này, bất kể độ sâu. Giá trị context có thể thuộc bất kỳ loại nào. Một component gọiuseContext(SomeContext)
bên trong provider sẽ nhận đượcvalue
của context provider tương ứng gần nhất phía trên nó.
SomeContext.Consumer
Trước khi useContext
tồn tại, có một cách cũ hơn để đọc context:
function Button() {
// 🟡 Cách cũ (không được khuyến nghị)
return (
<ThemeContext.Consumer>
{theme => (
<button className={theme} />
)}
</ThemeContext.Consumer>
);
}
Mặc dù cách cũ này vẫn hoạt động, code mới nên đọc context bằng useContext()
thay thế:
function Button() {
// ✅ Cách được khuyến nghị
const theme = useContext(ThemeContext);
return <button className={theme} />;
}
Props
children
: Một function. React sẽ gọi function bạn truyền vào với giá trị context hiện tại được xác định bởi cùng một thuật toán nhưuseContext()
, và render kết quả bạn trả về từ function này. React cũng sẽ chạy lại function này và cập nhật UI bất cứ khi nào context từ các component cha thay đổi.
Cách sử dụng
Tạo context
Context cho phép các component truyền thông tin xuống sâu mà không cần truyền props một cách rõ ràng.
Gọi createContext
bên ngoài bất kỳ component nào để tạo một hoặc nhiều context.
import { createContext } from 'react';
const ThemeContext = createContext('light');
const AuthContext = createContext(null);
createContext
trả về một đối tượng context. Các component có thể đọc context bằng cách truyền nó cho useContext()
:
function Button() {
const theme = useContext(ThemeContext);
// ...
}
function Profile() {
const currentUser = useContext(AuthContext);
// ...
}
Theo mặc định, các giá trị chúng nhận được sẽ là các giá trị mặc định mà bạn đã chỉ định khi tạo context. Tuy nhiên, bản thân điều này không hữu ích vì các giá trị mặc định không bao giờ thay đổi.
Context rất hữu ích vì bạn có thể cung cấp các giá trị động khác từ các component của bạn:
function App() {
const [theme, setTheme] = useState('dark');
const [currentUser, setCurrentUser] = useState({ name: 'Taylor' });
// ...
return (
<ThemeContext.Provider value={theme}>
<AuthContext.Provider value={currentUser}>
<Page />
</AuthContext.Provider>
</ThemeContext.Provider>
);
}
Bây giờ component Page
và bất kỳ component nào bên trong nó, bất kể độ sâu, sẽ “nhìn thấy” các giá trị context được truyền. Nếu các giá trị context được truyền thay đổi, React cũng sẽ render lại các component đọc context.
Đọc thêm về đọc và cung cấp context và xem các ví dụ.
Nhập và xuất context từ một file
Thông thường, các component trong các file khác nhau sẽ cần truy cập vào cùng một context. Đây là lý do tại sao việc khai báo context trong một file riêng là phổ biến. Sau đó, bạn có thể sử dụng câu lệnh export
để cung cấp context cho các file khác:
// Contexts.js
import { createContext } from 'react';
export const ThemeContext = createContext('light');
export const AuthContext = createContext(null);
Các component được khai báo trong các file khác sau đó có thể sử dụng câu lệnh import
để đọc hoặc cung cấp context này:
// Button.js
import { ThemeContext } from './Contexts.js';
function Button() {
const theme = useContext(ThemeContext);
// ...
}
// App.js
import { ThemeContext, AuthContext } from './Contexts.js';
function App() {
// ...
return (
<ThemeContext.Provider value={theme}>
<AuthContext.Provider value={currentUser}>
<Page />
</AuthContext.Provider>
</ThemeContext.Provider>
);
}
Điều này hoạt động tương tự như nhập và xuất các component.
Gỡ rối
Tôi không thể tìm thấy cách để thay đổi giá trị context
Code như thế này chỉ định giá trị context mặc định:
const ThemeContext = createContext('light');
Giá trị này không bao giờ thay đổi. React chỉ sử dụng giá trị này như một fallback nếu nó không thể tìm thấy một provider phù hợp ở trên.
Để làm cho context thay đổi theo thời gian, thêm state và bọc các component trong một context provider.