在react-query的快速入门文档中,有以下示例:
// Create a client
const queryClient = new QueryClient();
const App = function () {
return (
// Provide the client to your App
<QueryClientProvider client={ queryClient }>
<Todos />
</QueryClientProvider>
);
};
const Todos = function () {
// Access the client
const queryClient = useQueryClient();
// ...
return (
<>
...
</>
);
};
Run Code Online (Sandbox Code Playgroud)
但我不明白为什么我应该在 Todos 中使用 useQueryClient 挂钩。
// Access the client
const queryClient = useQueryClient();
Run Code Online (Sandbox Code Playgroud)
我的意思是我不能queryClient从主文件中导出实例:
// App.js
export const queryClient …Run Code Online (Sandbox Code Playgroud) 您可以在许多网站上找到这个短语,并且它被认为(?)有效:
React Context 通常用于避免 prop 钻探,但众所周知,存在性能问题。当上下文值更改时,所有使用的组件都
useContext将重新渲染。
而且:
React 团队提出了一个
useSelectedContext钩子来防止大规模 Context 的性能问题。有一个社区库:use-context-selector
然而,对于我来说,上述内容没有任何意义。难道我们不想重新渲染所有使用的组件吗useContext?绝对地!一旦上下文值发生变化,所有使用它的组件都必须重新渲染。否则,UI 将不会与状态同步。那么,性能问题到底是什么?
我们可以讨论如何不重新渲染不使用的 Context Provider 的其他子组件useContext,这是可以实现的(react docs):
<TasksContext.Provider value={tasks}>
<TasksDispatchContext.Provider value={dispatch}>
{children}
</TasksDispatchContext.Provider>
</TasksContext.Provider>
Run Code Online (Sandbox Code Playgroud)
通过使用上面的模式,我们可以避免重新渲染所有不使用useContext.
回顾一下:在我看来,正确使用 Context 时不存在性能问题。唯一会重新渲染的组件是那些应该重新渲染的组件。然而,几乎所有参考文献都坚持存在潜在的性能问题,并强调这是 Context 的警告之一。我错过了什么吗?
我正在使用应该支持 react 的 react-dom@16.6.1 和 react@16.6.1Context并尝试运行一个与react-context相同的简单示例:
应用程序.js
import React, { Component } from 'react';
import AppManger from './components/AppManger';
import './App.css';
export const ThemeContext = React.createContext({a1:'a1'});
class App extends Component {
render() {
return (
<div className="App">
<h1>Manage Storefront Services Products</h1>
<ThemeContext.Provider value="dark">
<AppManger />
</ThemeContext.Provider>
</div>
);
}
}
export default App;
Run Code Online (Sandbox Code Playgroud)
AppManger.js(没有上下文引用)
import React, { Component } from 'react'
import SearchBar from './SearchBar';
export default class AppManger extends Component {
constructor(props) {
super(props);
this.onSearchBarChange = …Run Code Online (Sandbox Code Playgroud) 前言/说明
我正在尝试将React的新挂钩函数用于我正在构建的电子商务网站,但是在解决购物车组件中的错误时遇到了问题。
我认为以我想通过使用多个Context组件保持全局状态模块化的事实作为开始讨论的重点。对于我提供的商品类型,我有一个单独的上下文组件,对于一个人的购物车中的商品,我有一个单独的上下文组件。
问题
我遇到的问题是,当我调度将组件添加到购物车的操作时,减速器将运行两次,就像我两次将商品添加到购物车一样。但是仅当它最初被渲染时,或者由于诸如显示之类的奇怪原因而被设置为hidden,然后又返回到block或由于z-index和可能的其他类似更改而改变。
我知道这有点冗长,但这是一个很挑剔的问题,因此我创建了两个演示该问题的代码笔:
您将看到我包含一个用于切换display组件的按钮。这将有助于展示CSS与问题的相关性。
最后,请用代码笔监视控制台,这将显示所有按钮的单击以及每个reducer的哪一部分已运行。在完整示例中,问题最明显,但在最小示例中,控制台语句显示了该问题。
问题区域
我已查明该问题与以下事实有关:我正在使用useContext挂钩的状态来获取项目列表。调用了一个函数来为我的useReducer钩子生成化简器,但是仅当使用了另一个钩子时才出现,我可以使用像钩子一样不会重新评估的函数,并且没有问题,但是我还需要我以前的上下文中的信息,因此解决方法无法真正解决我的问题。
相关连结
我已确定问题不是HTML问题,因此我将不包含我尝试过的HTML修复程序的链接。这个问题虽然是由CSS触发的,但并非植根于CSS,因此我也不会包含CSS链接。
我正在尝试使用后端对 REST API 的 API 调用产生的数据更新 React 应用程序的上下文。问题是我无法同步该功能。
我已经尝试过这篇博客文章https://medium.com/@__davidflanagan/react-hooks-context-state-and-effects-aa899d8c8014 中建议的这个解决方案,但它不适用于我的情况。
这是 textContext.js 的代码
import React, {useEffect, useState} from "react";
import axios from "axios";
var text = "Test";
fetch(process.env.REACT_APP_TEXT_API)
.then(res => res.json())
.then(json => {
text = json;
})
const TextContext = React.createContext(text);
export const TextProvider = TextContext.Provider;
export const TextConsumer = TextContext.Consumer;
export default TextContext
Run Code Online (Sandbox Code Playgroud)
这是我尝试从上下文访问数据的功能组件
import TextProvider, {callTextApi} from "../../../../services/textService/textContext";
function Profile()
{
const text = useContext(TextProvider);
console.log(text);
const useStyles = makeStyles(theme => ({
margin: {
margin: …Run Code Online (Sandbox Code Playgroud) 我知道我可以用 my 包装 HOC<Context.Provider>并在所有子组件中使用它。
我想在两个单独的组件中使用上下文,但它们嵌套在某个很深的地方,并且它们最近的父级位于应用程序根目录中的某个地方。我不想为(几乎)所有组件提供上下文,所以我想知道是否可以只包装这两个组件?
我尝试这样做,但只有第一个组件获得上下文。
应用程序结构如下所示:
<App>
<A1>
<A2>
<MyContext.Provider>
<Consumer1/>
</MyContext.Provider>
</A2>
</A1>
<B1>
<B2>
<MyContext.Provider>
<Consumer2/>
</MyContext.Provider>
</B2>
</B1>
</App>
Run Code Online (Sandbox Code Playgroud)
编辑:我错误地认为包装根组件将使上下文更改时重新渲染所有子组件。只有消费者才会重新渲染,因此包装根组件是完全可以的。
将useState钩子的 setter 函数用作回调 ref 函数是否安全?这是否会导致 Suspense 或其他即将到来的 React 更改出现问题?如果“是的,这没问题”,那就太酷了!如果“不”为什么不呢?如果“可能”,那么什么时候可以,什么时候不行?
我这么问是因为我的一个组件在调用 DOM API 之前需要挂载三个 refs。其中两个必需的 ref 是通过 JSXref道具在同一组件中分配的“普通” ref 。另一个 ref 将在稍后的某个时间通过 React 上下文分配到一个深层嵌套的组件中。我需要一种方法来在安装所有三个引用后强制重新渲染父组件,并useEffect在卸载任何引用时强制进行清理。
最初我编写了自己的回调引用处理程序,它调用了useState我存储在上下文提供程序中的setter。但后来我意识到useStatesetter 做了我自己的回调 ref 所做的一切。仅使用 setter 而不是编写自己的回调 ref 函数是否安全?或者有没有更好和/或更安全的方法来做我想做的事情?
我尝试谷歌搜索"useState" "callback ref"(和其他类似的关键字变体)但结果没有帮助,除了@theKashey的优秀use-callback-ref包我肯定会在其他地方使用(例如,当我需要将回调引用传递给组件时)需要一个 RefObject,或者当我需要一个回调并在本地使用一个 ref 时)但在这种情况下,所有回调需要做的就是在 ref 更改时设置一个状态变量,所以 Anton 的包在这里似乎有点过分了。
下面和https://codesandbox.io/s/dreamy-shockley-5dc74 有一个简化的例子。
import * as React from 'react';
import { useState, forwardRef, useEffect, createContext, useContext, useMemo } from 'react';
import { …Run Code Online (Sandbox Code Playgroud) 我是 React 新手,我想在我的班级中使用 useContext,我该如何解决这个问题?这是我当前代码的示例
import { Context } from '../context/ChatListContext'
const ChatList = ({ onAction }) => {
const {state, fetchChatList} = useContext(Context)
Run Code Online (Sandbox Code Playgroud)
我对我的班级也有同样的期待
import { Context } from '../context/ChatListContext'
class MainScreen extends Component {
//const {state, fetchChatList} = useContext(Context) *how do i declare this?
constructor(props) {
super(props)
this.state = { loading: true, showAction: false }
setTimeout(() => {
StatusBar.setBackgroundColor(primary)
}, 100)
}
...
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以启发我吗?
我\xe2\x80\x99已经使用React服务器组件近两周了,这个问题一直让我伤脑筋:如何为服务器组件提供上下文?例如,提供一个主题(例如深色|浅色模式)?我已经检查了 Nextjs 文档很多次,并且读到了同样的内容,就好像它会改变一样。它声明只有客户端组件可以使用Context。那么,如果服务器组件需要不基于服务器的数据,它将如何使用Context?我可以\xe2\x80\x99t 获取基于状态的数据。有没有人想办法解决这个问题?
\n <html>\n <body className="page-container">\n <ThemeProvider>\n {children} // Combination of Server and Client components\n </ThemeProvider>\n </body>\n </html>\nRun Code Online (Sandbox Code Playgroud)\nexport default async function ServerComponent(){\n ...\n const theme = useContext(ThemeContext) // Would give an error; not a client component\n ...\n return (\n <div className={theme}>\n ...\n </div>\n)\n}\nRun Code Online (Sandbox Code Playgroud)\n我已经完成了 Next.js beta 文档中所说的所有内容:将提供程序放在客户端组件中,并让服务器组件成为所述客户端组件的子组件。现在,我只是想知道如何使用服务器组件中的上下文;它适用于客户端组件,因为它们允许使用钩子,但不适用于服务器组件。
\njavascript reactjs react-context react-server-components next.js13
我正在使用 lerna 创建一个 monorepo,其中我有一个这样的结构:
root
packages
application - Our root application
components - Just some react components, that are to be used by the application
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是我正在使用 Material-UI 及其主题功能,在应用程序根目录中,我们将有一个 ThemeProvider:
import { ThemeProvider } from '@material-ui/styles';
//...
function App() {
return (
<ThemeProvider theme={theme}>
<MyMaterialComponent/>
</ThemeProvider>
);
}
Run Code Online (Sandbox Code Playgroud)
然后在库组件中,我们使用主题,在我们的例子中使用makeStyles钩子。
import React from 'react';
import { makeStyles } from '@material-ui/styles';
import Card from "@material-ui/core/Card";
const useStyles = makeStyles(theme => {
console.log(theme); //When this component doesn't have …Run Code Online (Sandbox Code Playgroud) react-context ×10
reactjs ×10
javascript ×3
react-hooks ×3
lerna ×1
material-ui ×1
next.js13 ×1
react-native ×1
react-query ×1
use-context ×1