Css toàn cầu phản ứng

Bối cảnh cung cấp phương pháp truyền dữ liệu xuyên suốt cây thành phần mà không cần phải truyền đạo cụ một cách thủ công qua từng cấp độ

Thông thường với một ứng dụng React, dữ liệu được truyền từ trên xuống (cha tới con) thông qua props, điều này có vẻ khá trống rỗng đối với một số loại props (Ví dụ như tùy chọn ngôn ngữ, chủ đề giao diện người dùng) chúng thường được sử dụng . Bối cảnh cung cấp một cách làm cho phép chúng ta chia sẻ các giá trị giống như vậy giữa các thành phần mà không cần truyền giá trị tới tất cả các cấp trong cây thành phần

  • When any should use Context
  • Trước khi bạn sử dụng bối cảnh
  • API

    • Phản ứng. tạo bối cảnh
    • Định nghĩa bài văn. Các nhà cung cấp
    • Tầng lớp. bối cảnhType
    • Định nghĩa bài văn. Khách hàng
    • Định nghĩa bài văn. tên hiển thị
  • Ví dụ

    • Bối cảnh động
    • Update Context from Nested Component
    • Use Multiple Contexts
  • Hãy cẩn thận
  • API kế thừa

When any should use Context

Bối cảnh được thiết kế để chia sẽ dữ liệu khi chúng được xem là “dữ liệu toàn cầu” của toàn bộ ứng dụng React, giả sử như thông tin về người dùng hiện đang đăng nhập, chủ đề hoặc ngôn ngữ mà người dùng đã chọn. Ví dụ, ở đoạn mã bên dưới, chúng ta truyền một prop “theme” để tạo kiểu cho một thành phần Button

class App extends React.Component {
  render() {
    return <Toolbar theme="dark" />;
  }
}

function Toolbar(props) {
  // The Toolbar component must take an extra "theme" prop  // and pass it to the ThemedButton. This can become painful  // if every single button in the app needs to know the theme  // because it would have to be passed through all components.  return (
    <div>
      <ThemedButton theme={props.theme} />    div>
  );
}

class ThemedButton extends React.Component {
  render() {
    return <Button theme={this.props.theme} />;
  }
}

Sử dụng bối cảnh, chúng ta có thể tránh được đạo cụ truyền thông qua các yếu tố trung gian

// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}

Trước khi bạn sử dụng bối cảnh

Phần chủ ngữ cảnh được sử dụng khi một số dữ liệu cần được truy cập bởi nhiều thành phần ở nhiều tầng khác nhau. Sử dụng nó một cách cẩn thận bởi vì điều đó sẽ làm thành phần trở nên khó tái sử dụng hơn

Nếu bạn chỉ muốn sử dụng bối cảnh để tránh việc truyền một số đạo cụ qua nhiều cấp độ, thì thành phần thành phần thường là một giải pháp đơn giản hơn so với bối cảnh

Ví dụ, một thành phần

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
0 truyền
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
1 và
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
2 chống lại một số cấp độ hạ cấp để các thành phần
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
3 và
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
4 có thể đọc được

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>

Bạn có thể cảm thấy dư thừa khi truyền

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
1 và
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
6 đạo cụ thông qua nhiều cấp độ nếu chỉ có thành phần
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
4 thực sự cần thiết để đến với nó. Nó cũng khá khó chịu Mỗi khi thành phần
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
4 cần thêm đạo cụ từ các tầng trên cùng, bạn phải thêm tất cả các đạo cụ đó ở tất cả các tầng trung gian

Một cách để giải quyết vấn đề này mà không sử dụng bối cảnh là thành phần truyền thông tự nhiên của

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
4 bằng cách này, các thành phần trung gian không cần thiết phải giữ
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
1 hoặc đạo cụ
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
2

// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}
5

Với sự thay đổi này, chỉ có tầng trên cùng của thành phần Trang được biết là thành phần

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
3 và
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
4 sử dụng
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
1 và
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
6

Sự đảo ngược quyền kiểm soát (đảo ngược quyền kiểm soát) này có thể giúp mã của bạn rõ ràng hơn ở nhiều trường hợp bằng cách giảm số lượng đạo cụ cần phải truyền xuyên suốt ứng dụng của bạn và cho phép kiểm soát đến thành phần gốc. Tuy nhiên, đây không phải là một lựa chọn tốt cho mọi trường hợp, chuyển đổi mức độ phức tạp lên mức cao hơn trong cây thành phần khiến những thành phần ở cấp cao (thành phần cấp cao hơn) trở nên phức tạp và bắt buộc đối với những thành phần đó

Bạn không bị giới hạn vào một con duy nhất cho mỗi thành phần. Bạn có thể truyền nhiều con, hay thậm chí chí là nhiều “khe” tách biệt cho con, Như tài liệu ở đây

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
0

Mẫu này hoàn toàn có hiệu quả cho nhiều trường hợp khi bạn cần tách một thành phần con khỏi các thành phần trung gian của nó. Bạn có thể tiến xa hơn nữa với các đạo cụ kết xuất nếu thành phần con cần giao tiếp với thành phần cha mẹ trước khi kết xuất

Tuy nhiên, đôi khi có những dữ liệu trùng lặp cần được truy cập bởi nhiều thành phần trong cây thành phần và ở nhiều tầng khác nhau. Context cho phép bạn “Phát sóng (broadcast)” những dữ liệu như vậy, và trao đổi nó đến tất cả những thành phần bên dưới. Ví dụ như khi sử dụng ngữ cảnh có thể sẽ đơn giản hơn so với những lựa chọn thay thế bao gồm quản lý ngôn ngữ hiện tại, chủ đề, hay bộ nhớ đệm dữ liệu

API

// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light'); class App extends React.Component { render() { // Use a Provider to pass the current theme to the tree below. // Any component can read it, no matter how deep it is. // In this example, we're passing "dark" as the current value. return ( ); } } // A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() { return (
); } class ThemedButton extends React.Component { // Assign a contextType to read the current theme context. // React will find the closest theme Provider above and use its value. // In this example, the current theme is "dark". static contextType = ThemeContext; render() { return

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
2

Create a Context object. Khi React render một component mà nó subcribe to Context object này, nó sẽ đọc giá trị hiện tại của context đó từ

// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}
57 gần nhất trên cây component

Đối số

// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}
58 chỉ được sử dụng khi một thành phần không có Nhà cung cấp nào bên trên nó trong cây thành phần. Điều này có thể hữu ích cho việc kiểm tra thành phần một cách cô lập mà không cần phải bọc chúng lại. Lưu ý. truyền
// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}
59 với tư cách là một nhà cung cấp giá trị sẽ không khiến các thành phần tiêu thụ sử dụng
// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}
58

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
8

Mỗi đối tượng Context đi cùng với một thành phần Provider React cho phép thành phần tiêu thụ theo dõi sự thay đổi của bối cảnh đó

Thành phần nhà cung cấp nhận được một

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
02 chỗ dựa để chuyển đến các thành phần tiêu thụ mà nó là con của Nhà cung cấp này. Một nhà cung cấp có thể kết nối với nhiều người tiêu dùng. Các nhà cung cấp có thể lồng nhau để ghi đè giá trị sâu hơn trong cây thành phần

Tất cả người tiêu dùng của một Nhà cung cấp sẽ được đăng ký lại bất kỳ khi nào

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
02 của Nhà cung cấp thay đổi. Sự truyền từ Nhà cung cấp đến người tiêu dùng con của nó (bao gồm
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
04 và
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
05) không hợp lệ thuộc vào phương pháp
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
06, vì vậy người tiêu dùng được cập nhật ngay cả khi một thành phần thoát ra khỏi sự cập nhật đó

Những thay đổi này được xác định bằng cách so sánh những giá trị mới và cũ sử dụng chung một thuật toán như

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
07

Lưu ý

Những cách thay đổi được xác định là có thể gây ra một số vấn đề khi truyền đối tượng như một

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
02. xem Hãy cẩn thận

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
7

Thuộc tính

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
20 trong một lớp có thể được gán vào một đối tượng ngữ cảnh được tạo bởi
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
21. Điều này giúp bạn thu nhận giá trị gần nhất ở thời điểm hiện tại của loại Ngữ cảnh sử dụng
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
22. Bạn có thể tham khảo điều này trong mọi phương pháp vòng đời bao gồm chức năng kết xuất

Lưu ý

You only can subcribe to a context duy nhất sử dụng API này. Nếu bạn muốn đọc nhiều hơn một ngữ cảnh, hãy tham khảo Consuming Multiple Contexts

Bạn có thể sử dụng chức năng thử nghiệm cú pháp trường lớp công khai, bạn có thể sử dụng trường lớp tĩnh để khởi động

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
20 của mình

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
2

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
4

When a React component subcribe to the change of context. Điều này cho phép bạn đăng ký theo ngữ cảnh trong một thành phần chức năng

Request a function as a child. Hàm nhận giá trị ngữ cảnh hiện tại và trả về một nút React. Tham số

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
02 truyền đến chức năng sẽ bằng với
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
02 chỗ dựa của Nhà cung cấp gần nhất trong ngữ cảnh này trên thành phần cây. If no Provider any for this context on it, tham số
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
02 sẽ tương đương với
// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}
58 đã được truyền tới
<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
29

Lưu ý

Để biết thêm thông tin về mẫu 'chức năng như một đứa trẻ', hãy xem đạo cụ kết xuất

Đối tượng ngữ cảnh nhận một thuộc tính

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
81 kiểu chuỗi (chuỗi). React DevTools sử dụng chuỗi này để xác định cái sẽ hiển thị cho ngữ cảnh

Với ví dụ dưới đây, thành phần sẽ hiển thị dưới dạng MyDisplayName trong DevTools

// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}
0

ví dụ

Bối cảnh động

Một ví dụ phức tạp hơn với các giá trị động cho chủ đề

chủ đề-bối cảnh. js

// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}
1

nút theo chủ đề. js

// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}
2

ứng dụng. js

// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}
3

Update Context from a Nested Component

Chúng ta thường cần cập nhật ngữ cảnh từ một thành phần đã được lồng ở nơi nào sâu trong cây thành phần. Trong trường hợp này, bạn có thể chuyển một hàm xuống ngữ cảnh để cho phép người tiêu dùng cập nhật ngữ cảnh đó

chủ đề-bối cảnh. js

// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}
4

chủ đề-toggler-nút. js

// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}
5

ứng dụng. js

// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}
6

Tiêu thụ nhiều ngữ cảnh

Để giữ cho context re-rendering nhanh chóng, React cần làm cho mỗi context consumer tách rời nhau trong component tree

// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}
7

Nếu có hai hoặc nhiều giá trị ngữ cảnh được sử dụng giống nhau, bạn có thể muốn sử dụng thành phần chống đỡ kết xuất của chính mình

Hãy cẩn thận

Bởi vì bối cảnh sử dụng danh tính tham chiếu để xác định khi nào nên kết xuất lại, có một số vấn đề nguy hiểm có thể kích hoạt kết xuất lại một cách vô cùng tình cảm đối với người tiêu dùng khi nhà cung cấp kết xuất lại. Ví dụ, đoạn mã bên dưới sẽ kết xuất lại tất cả người tiêu dùng mỗi lần Nhà cung cấp kết xuất lại bởi vì một đối tượng mới sẽ luôn được tạo cho

<Page user={user} avatarSize={avatarSize} />
// .. được renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// .. được renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// .. được renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
Link>
02

// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}
8

Để giải quyết vấn đề này, hãy nâng giá trị đó lên trạng thái của cha

// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}
9

API kế thừa

Lưu ý

React vừa mang đến một context API test. API cũ sẽ hỗ trợ trong tất cả phiên bản 16. x, nhưng những ứng dụng sử dụng nó nên nâng cấp lên phiên bản mới hơn. API cũ sẽ bị xóa trong tương lai qua những lần cập nhật lớn nhất của React. Tham khảo tài liệu ngữ cảnh kế thừa tại đây