useContext 在 useQuery 时返回 null
Posted
技术标签:
【中文标题】useContext 在 useQuery 时返回 null【英文标题】:useContext returning null upon useQuery 【发布时间】:2021-07-18 05:16:34 【问题描述】:我正在为设置页面制作一个包装器,以便它可以在每个设置页面上重复使用。在其中,有一个 Context Provider,我在其中传递用户数据,但尽管查询成功,但它似乎从未传递任何东西。
SettingsWrap.tsx
export const UserContext = React.createContext(null);
const SettingsWrap = ( children ) =>
const [session] = useSession();
const data, loading = useQuery<SettingsData, SettingsVars>(
SETTINGS_QUERY,
variables:
id: session?.id,
,
skip: !session,
);
return (
<Grid container spacing=2>
<Grid item xs=12 sm=4>
<SettingList />
</Grid>
data && !loading ? (
<UserContext.Provider value=data.userId>
<Grid
item
xs=12
sm=8
style= height: "100vh", overflow: "auto"
>
<Container>children</Container>
</Grid>
</UserContext.Provider>
) : (
<Grid
item
xs=12
sm=8
style=
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100vh",
>
<CircularProgress />
</Grid>
)
</Grid>
);
;
AccountSettings.tsx
const user: UserInterface = useContext(UserContext); // THIS IS NULL
这段代码有什么问题?
【问题讨论】:
<AccountSettings/>
组件是 <SettingsWrap />
的子组件吗?
是的,那里有用户被传递到的子组件。
其他子组件是否可以通过UserContext
访问用户?
不,它们的 props 由拥有 useContext 的父组件提供
【参考方案1】:
上下文有一个默认值,然后可以通过使用提供程序设置为不同的其他值,就像您所做的那样。提供者的值仅影响组件的子子树中的组件。相反,上下文的当前值是最近的祖先提供者设置的值,如果不存在,则为上下文的默认值。
检查以下示例:
export const NumberContext = React.createContext(0); // default value
export default function App()
return (
<div>
<Consumer /> // #1, shows 0
<NumberContext.Provider value=1>
<Consumer /> // #2, shows 1
<NumberContext.Provider value=2>
<Consumer /> // #3, shows 2
</NumberContext.Provider>
<div>
<div>
<Consumer /> // #4, shows 1
</div>
</div>
</NumberContext.Provider>
</div>
);
export function Consumer()
const number = useContext(NumberContext)
return <p>number</p>
这是一个带有此示例的沙盒:https://codesandbox.io/s/react-contexts-6dlh1
第一个Consumer
(#1
) 没有祖先提供程序,因此它显示创建的上下文的默认值,即 0。
第二个 Consumer
(#2
) 是值为 1 的提供者的直接子代,因此显示值为 1。
第三个 Consumer
(#3
) 有两个祖先提供者,但最近的祖先提供者提供值 2,所以这就是该组件显示的值。
第四个也是最后一个Consumer
(#4
) 嵌套在第一个提供者之下(因为它位于第二个提供者之外,但仍在第一个提供者的子层次结构内)。因此它有一个值为 1 的祖先提供者,因此它也将显示值为 1。
在您的示例中,SettingsList
(AccountSettings
的父级)是UserContext
的假定使用者,没有祖先提供者(因为它不位于组件树中包含的提供者之下)。因此,运行useContext(UserContext)
将始终在组件的子树中返回null
,默认值或UserContext
。尝试将SettingsList
放在具有祖先提供程序的子树中,它会起作用。
【讨论】:
这就是我后来在尝试更多玩弄时才意识到的,谢谢!【参考方案2】:显然,当我在传递“用户”的子组件中使用 useContext 时,它工作得非常好。在父组件中使用上下文而不是实际组件是我的错误。
【讨论】:
以上是关于useContext 在 useQuery 时返回 null的主要内容,如果未能解决你的问题,请参考以下文章
返回上一个屏幕时执行 useQuery() 挂钩反应原生堆栈导航器
在功能组件中,useContext 在 console.log 中工作,但在渲染时返回错误