ReactJS - getChildContext() 方法



getChildContext() 函数是 React 中的组件生命周期函数。此函数允许父组件与其子组件交换指定的信息。它类似于创建一个特定的盒子(上下文),父组件可以在其中存储重要数据。父组件决定放入盒子中的内容,并允许子组件访问它,而无需通过使用 getChildContext() 直接传递。这种通信方式使事情井然有序,并简化了应用程序不同部分之间如何相互通信,类似于一个家庭有一种特定的方式来讨论关键信息,而无需单独与每个成员沟通。

语法

getChildContext()

为了使用 getChildContext(),组件必须定义一个名为 childContextTypes 的静态属性,该属性指定上下文数据的预期类型。

示例

示例 1

让我们使用 getChildContext() 函数创建一个示例。在这个例子中,我们将创建一个简单的应用程序,通过上下文传递用户数据来显示用户信息。

import PropTypes from 'prop-types';
import React, { Component } from 'react';

// Create a context
const UserContext = React.createContext({
   username: 'Guest',
   age: 0,
});

// Create a component
class UserProvider extends Component {
   // Define child context types
   static childContextTypes = {
      user: PropTypes.shape({
      username: PropTypes.string,
      age: PropTypes.number,
   }),
   };   
   getChildContext() {
      return {
         user: {
            username: this.props.username,
            age: this.props.age,
         },
      };
   }
   
   render() {
      // Render the child components
      return this.props.children;
   }
}

// Create a component that consumes user data from context
class UserInfo extends Component {
   static contextTypes = {
      user: PropTypes.shape({
         username: PropTypes.string,
         age: PropTypes.number,
      }),
   };   
   render() {
      return (
         <div>
            <p>Welcome, {this.context.user.username}!</p>
            <p>Your age: {this.context.user.age}</p>
         </div>
      );
   }
}

// Create the main App component
class App extends Component {
   render() {
      return (
         // Wrap the UserInfo component with the UserProvider
         <UserProvider username="Amit" age={25}>
            <UserInfo />
         </UserProvider>
      );
   }
}

export default App;

输出

welcome amit

在上面的代码中,App 组件使用 UserProvider 包装 UserInfo 组件,以通过上下文传递用户数据。

示例 2

这是一个使用 getChildContext() 在 React 应用中创建简单主题上下文的另一个示例 -

import React, { Component } from 'react';
import PropTypes from 'prop-types';

// Create a context for the theme
const ThemeContext = React.createContext({
   theme: 'light',
   toggleTheme: () => {},
});

// Create a component for providing the theme
class ThemeProvider extends Component {
   
   // Define child context types
   static childContextTypes = {
      themeContext: PropTypes.shape({
         theme: PropTypes.string,
         toggleTheme: PropTypes.func,
      }),
   };
   
   // Set initial state
   state = {
      theme: 'light',
   };
   
   // Define a function to toggle the theme
   toggleTheme = () => {
      this.setState((prevState) => ({
         theme: prevState.theme === 'light' ? 'dark' : 'light',
      }));
   };
   
   // Provide the theme context through getChildContext()
   getChildContext() {
      return {
         themeContext: {
            theme: this.state.theme,
            toggleTheme: this.toggleTheme,
         },
      };
   }
   
   render() {
      // Render the child components
      return this.props.children;
   }
}

// Create a component
class ThemedComponent extends Component {
   // Define context types
   static contextTypes = {
      themeContext: PropTypes.shape({
         theme: PropTypes.string,
         toggleTheme: PropTypes.func,
      }),
   };
   
   render() {
      return (
         <div style={{ background: this.context.themeContext.theme === 'light' ? '#fff' : '#333', color: this.context.themeContext.theme === 'light' ? '#333' : '#fff' }}>
            <p>Current Theme: {this.context.themeContext.theme}</p>
            <button onClick={this.context.themeContext.toggleTheme}>Toggle Theme</button>
         </div>
      );
   }
}

// Create the main App component
class ThemeApp extends Component {
   render() {
      return (
         <ThemeProvider>
            <ThemedComponent />
         </ThemeProvider>
      );
   }
}

export default ThemeApp;

输出

current theme

在上面的示例中,ThemeProvider 组件使用 getChildContext() 提供一个主题上下文,默认主题为“light”,并提供一个切换主题的函数。ThemedComponent 然后使用此上下文显示有关当前主题的信息和一个切换按钮。ThemeApp 组件在 ThemeProvider 的上下文中渲染 ThemedComponent。

示例 3

让我们再创建一个使用 getChildContext() 在 React 应用中管理用户身份验证的示例 -

import React, { Component } from 'react';
import PropTypes from 'prop-types';

// Create a context for user authentication
const AuthContext = React.createContext({
   isAuthenticated: false,
   login: () => {},
   logout: () => {},
});

// Create a component for providing authentication context
class AuthProvider extends Component {
   static childContextTypes = {
      authContext: PropTypes.shape({
         isAuthenticated: PropTypes.bool,
         login: PropTypes.func,
         logout: PropTypes.func,
      }),
   };
   
   // Set initial state
   state = {
      isAuthenticated: false,
   };
   
   // Define a function to handle user login
   login = () => {
      this.setState({
         isAuthenticated: true,
      });
   };
   
   // Define a function to handle user logout
   logout = () => {
      this.setState({
         isAuthenticated: false,
      });
   };
   
   // Provide the authentication context through getChildContext()
   getChildContext() {
      return {
         authContext: {
            isAuthenticated: this.state.isAuthenticated,
            login: this.login,
            logout: this.logout,
         },
      };
   }
   
   render() {
      // Render the child components
      return this.props.children;
   }
}

// Create a component that consumes the authentication context
class AuthComponent extends Component {
   // Define context types
   static contextTypes = {
      authContext: PropTypes.shape({
         isAuthenticated: PropTypes.bool,
         login: PropTypes.func,
         logout: PropTypes.func,
      }),
   };
   
   render() {
      return (
         <div>
            <p>User is {this.context.authContext.isAuthenticated ? 'authenticated' : 'not authenticated'}</p>
            {this.context.authContext.isAuthenticated ? (
               <button onClick={this.context.authContext.logout}>Logout</button>
            ) : (
               <button onClick={this.context.authContext.login}>Login</button>
            )}
         </div>
      );
   }
}

// Create the main App component
class App extends Component {
   render() {
      return (
         <AuthProvider>
            <AuthComponent />
         </AuthProvider>
      );
   }
}

export default App;

输出

aunthenticated user

在上面的应用程序中,AuthProvider 组件使用 getChildContext() 提供一个身份验证上下文,其默认值为 isAuthenticated 设置为 false。它还具有管理登录和注销操作的功能。AuthComponent 使用此上下文来确定用户是否已认证,并提供登录和注销按钮。

局限性

从 React 16.3 开始,getChildContext() 函数已弃用,建议使用新的 Context API 来代替。

总结

getChildContext() 函数可用于在 React 组件中提供上下文,建议开发人员采用新的 Context API 以提高可读性和未来的兼容性。

reactjs_reference_api.htm
广告