[英]Using React context in a component
假设我创建了一个简单的 React 上下文来检查我是否已连接
import NetInfo, { NetInfoState } from '@react-native-community/netinfo';
import Constants, { AppOwnership } from 'expo-constants';
import React, { PropsWithChildren, createContext, useContext, useEffect, useState } from 'react';
import { Platform } from 'react-native';
const ConnectionContext = createContext<boolean>(undefined);
export function ConnectionProvider({ children }: PropsWithChildren<any>): JSX.Element {
const [connected, setConnected] = useState(false);
function handleConnectionChange(netInfo: NetInfoState) {
setConnected(
(Platform.OS === 'ios' && Constants.appOwnership === AppOwnership.Expo) ||
(netInfo.isConnected && (netInfo.isInternetReachable ?? true))
);
}
useEffect(() => {
const subscriptionCancel = NetInfo.addEventListener(handleConnectionChange);
return () => subscriptionCancel();
}, []);
return <ConnectionContext.Provider value={connected}>{children}</ConnectionContext.Provider>;
}
export function useConnection() {
return useContext(ConnectionContext);
}
我想知道我是否想在我现有的组件XYZ
使用它,是否有比以下更迂回的方法
从:
export function XYZ() {
...xyz code...
}
至:
export function XYZ() {
return (
<ConnectionContextProvider>
<RealXyz>
</ConnectionContextProvider>
);
}
function RealXyz() {
const connected = useConnection();
...xyz code...
}
我不认为上下文真的是必要的,因为连接更像是一种单例类型的东西。 下面的代码应该在它自己的文件中,你可以在你的应用程序的任何地方导入这个钩子。
let _isConnected = false;
export const useConnection = () => {
const [isConnected, setConnected] = useState(_isConnected);
useEffect(() => {
function handleConnectionChange(netInfo: NetInfoState) {
_isConnected = (Platform.OS === 'ios' && Constants.appOwnership === AppOwnership.Expo) ||
(netInfo.isConnected && (netInfo.isInternetReachable ?? true))
setConnected(_isConnected);
}
const subscriptionCancel = NetInfo.addEventListener(handleConnectionChange);
return () => subscriptionCancel();
}, []);
return isConnected;
}
解释:
假设您有两个使用此钩子的组件。 当您的应用程序首次呈现时,只会安装 ComponentA。 一段时间后,连接状态更改为true
。 然后一段时间后安装 ComponentB。 我们希望 ComponentB 知道连接状态当前为true
,这就是我们使用单例模式(例如私有全局变量_isConnected
)的原因。 有多个事件侦听器并不重要,因为它们很便宜并且在卸载组件时会被删除。
如果您有需要在多个组件之间共享的数据,并且您不想通过 props 将其传递到树中,则 Context 很方便。
从文档:
Context 提供了一种通过组件树传递数据的方法,而无需在每个级别手动向下传递 props。
在您的示例中,我将使用useState
,但是为了让您了解可以选择上下文检查以下代码段的位置:
...
function ABC() {
const connected = useConnection();
...abc code...
}
function ABCParent() {
return <ABC />
}
...
function XYZ() {
const connected = useConnection();
...xyz code...
}
function XYZParent() {
return <XYZ />
}
...
function App() {
return (
<ConnectionContextProvider>
<ABCParent />
<XYZParent />
</ConnectionContextProvider>
)
}
使用上下文的两个组件在树的“深处”和单独的分支中。 这个例子有点简单,你可以很容易地通过 props 传递你需要的数据,并且仍然有一个可维护的代码库。
但最终,如果您觉得您的数据模型可以是“全局的”,并且您在单独的分支或多个级别的同一分支中有足够的依赖项,请使用上下文 API。
我发现使用上下文 API 有用的一些数据模型示例是主题、应用程序设置、路由和翻译。
需要注意的一件事:依赖于上下文的组件的可重用性将降低(这在项目之间更相关),有时您可以选择组合而不是使用上下文 API。 查看文档的使用前上下文部分以获取有关此内容的更多信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.