标签: react-context

使用 Context API 与 CloneElement 来传递直接后代的 props

所以,我有两个组件,一个组件始终是另一个组件的直系后代。我想将道具从父组件传递给子组件。可能有多个子组件。有两种方法可以实现它。

React.Children.map(children, (child) =>
  React.cloneElement(child, { someProp: 'value' })
)
Run Code Online (Sandbox Code Playgroud)

或使用上下文 API

<Context.Provider value={{ someProp: 'value' }}>
  {this.props.children}
</Context.Provider>
Run Code Online (Sandbox Code Playgroud)

两者都会产生相同的 DOM 结构,但是 Context API 的代码稍微多一些,并且会产生更多的 React 组件。

那么哪一款更注重性能,值得推荐。我找不到与此比较相关的任何讨论,因此在这里询问。

javascript performance reactjs react-context

7
推荐指数
1
解决办法
1766
查看次数

如何实现新的react-redux v6.0.0

我试图迁移react-redux v5.X.Xv6.0.0该站点,似乎没有任何文档。我正在使用以下版本: "react": "^16.4.2" "redux": "^4.0.0" "react-redux": "^6.0.0"

官方更改日志说。

不再支持将存储作为道具传递给已连接的组件。相反,您可以向和都传递自定义context = {MyContext}属性。您也可以通过{context:MyContext}作为连接选项。链接在这里

这是我的根 index.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import { configureStore, history } from './Store';
import App from './App.hot';

import 'antd/dist/antd.min.css';
const reduxStore = configureStore();
ReactDOM.render(<App store={reduxStore} history={history} />, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)

这是我的app.jsx(根组件)

import React from 'react';
import PropTypes from 'prop-types';
import { Provider, connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { ConnectedRouter } from 'connected-react-router';
import …
Run Code Online (Sandbox Code Playgroud)

javascript reactjs react-redux react-context

7
推荐指数
1
解决办法
5224
查看次数

如何在 AJAX 请求后使用反应上下文 api 值更新 Formik 初始值?

不过,我面临的问题是,我想在整个组件树状结构中模仿 React 中 FlaskLogin current_user 的行为。对于不熟悉 FlaskLogin 的任何人,current_user只需存储当前登录用户的会话。

为此,我决定使用 React 上下文 api。我所做的是在顶级组件中,我将一个 UserProvider 包裹在应用程序周围,如下所示:

<UserProvider value={this.state.user}>
    // Main Component.
</UserProvider>
Run Code Online (Sandbox Code Playgroud)

状态在构造函数中定义:

constructor() {
    super();
    this.state = {
      user: {
        id: -1,
        username: ‘test username’,
        email: 'test email’,
      },
    };
  }
Run Code Online (Sandbox Code Playgroud)

然后我在 componentDidMount 中调用一个 Ajax 请求来获取 current_user。

componentDidMount() {
    const state = this;
    post('/get_current_user').then(function success(data) {
      state.setState({
        user: {
          id: data.data.id,
          username: data.data.username,
          email: data.data.email,
        },
      });
    }).catch(function exception() {
      throw new Error('Failed to grab current user.');
    });
  } …
Run Code Online (Sandbox Code Playgroud)

javascript reactjs formik react-context

7
推荐指数
1
解决办法
7056
查看次数

您应该使用 React Context Provider 包装整个应用程序吗?

如果用户经过身份验证并可以通过React Context API访问它,我想保存一个简单的布尔值 + userID 。

许多指南用上下文提供者包装了他们的根组件。对我来说,包装整个应用程序似乎很浪费。另一方面,我需要在我的所有主页中提供此信息。

用 React Context Provider 包装整个应用程序会产生负面影响吗?

例子:

class App extends Component {
render() {
    return (
        <MyProvider>
            <div className="App">
                    <h1 className="App-title">Welcome to my web store</h1>
                <ProductList />
            </div>
        </MyProvider>
    );
}
Run Code Online (Sandbox Code Playgroud)

}

我使用本指南作为参考。

我没有任何 React Redux 经验,所以这对于以前使用过这个框架的每个人来说可能都很自然。

研究 Google 后发现了许多关于如何实现 React Context 或使用 HOC 的指南,但我点击的 15 个指南并没有回答我的问题。

reactjs react-context

7
推荐指数
1
解决办法
5139
查看次数

如何在Gatsby网站中保留或重新提供React Context

我将Gatsby用作静态网站生成器。我使用React Context API来存储用户已通过身份验证的信息。

在开发模式下,当我键入任何重定向到404错误页面的URL时,上下文数据将丢失。当我导航到有效页面时,以前登录的用户不再登录。

我之前从未使用过React Context,所以不确定如何处理。那是预期的行为吗?有什么方法可以保留用户特定的React Context?我是否需要从后端重新提供上下文?还是我只是犯了一个错误?最好的行动方针是什么?

我想以某种方式将上下文保留在浏览器中,直到会话超时。尚未执行来自后端的会话处理。

编辑:我刚刚用gatsby构建和gatsby服务测试了这一点。当重定向到404错误页面时,内置的gatsby网站会保留上下文。但是,当导航到完全不同的URL(例如www.google.com)时,上下文仍然丢失。

现在我的问题是:如何在不让用户再次手动登录的情况下为上下文提供登录信息?Cookie检查?抱歉,如果我要问一个明显的问题。我从未实现过会话或cookie。

这是我的AuthContextProvider包装器类:

import React from "react";

export const AuthContext = React.createContext();

export class AuthContextProvider extends React.Component {
  state = {
    authenticated: false,
    toggleLogin: () => {},
    userid: null,
  };

  render() {
    return (
      <AuthContext.Provider
        value={{
          authenticated: this.state.authenticated,
          userid: this.state.userid,
          toggleLogin: () => {
            const previousValueState = this.state.authenticated;
            this.setState(state => ({
              authenticated: !previousValueState,
              userid: 2,
            }));
          },
        }}
      >
        {this.props.children}
      </AuthContext.Provider>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

我用Context Provider将整个应用程序包装在根布局中:

export default function RootLayout({ …
Run Code Online (Sandbox Code Playgroud)

reactjs gatsby react-context

7
推荐指数
1
解决办法
410
查看次数

React Portal 如何在不同的子树中保留 Provider 的上下文?

因此,门户解决的一个有趣且令人惊奇的属性是保留来自提供者的上下文,即使您的组件需要在其他地方呈现也是如此。如果您使用 ContextProvider 包装组件子树,则在该子树中呈现的任何组件都将有权访问上下文值。

反过来,如果您在子树之外渲染某些内容,它就无法访问该上下文。React Portals 解决了这个问题,所以如果你想渲染子树之外的东西,你可以在同一个子树内完成它。我认为React 文档对此有所涉及

无论子级是否是门户,诸如上下文之类的功能都完全相同,因为无论 DOM 树中的位置如何,门户仍然存在于 React 树中。

我想我并没有概念化它实际上是如何工作的。React Portal 如何能够访问 Context 而无需在同一子树中渲染?听起来在幕后,Portal 是“React Tree”的一部分?那么一定有一些奇特的“传递信息然后渲染门户逻辑”?明确我的问题

门户究竟如何工作来保留对上下文值的访问?

javascript reactjs react-context react-portal

7
推荐指数
1
解决办法
2904
查看次数

如何从 Apollo set Context Http Link 访问 React 上下文

我正在尝试访问我的 Apollo 客户端的 setContext 函数中的反应上下文值。我希望能够使用反应上下文值动态更新每个 graphql 请求的标头。但是我遇到了一个错误,日志中没有可见的错误消息。我正在尝试做的可能吗?

import React, { useState, useContext } from "react";
import { render } from "react-dom";

import ApolloClient from "apollo-client";
import { ApolloProvider } from "react-apollo";
import { createHttpLink } from "apollo-link-http";
import { setContext } from "apollo-link-context";
import { InMemoryCache } from "apollo-cache-inmemory";

import Select from "./Select";
import CurrencyContext from "./CurrencyContext";
import ExchangeRates from "./ExchangeRates";

const httpLink = createHttpLink({
  uri: "https://48p1r2roz4.sse.codesandbox.io"
});

const authLink = setContext((_, { headers }) => {

  const token = …
Run Code Online (Sandbox Code Playgroud)

reactjs react-apollo apollo-client react-context react-hooks

7
推荐指数
1
解决办法
809
查看次数

使用它来存储 JSX 组件以便在其他地方显示是滥用上下文吗?

我有一个应用程序,用户将单击应用程序的各个部分,这将在右侧的抽屉中显示某种配置选项。

我对此的解决方案是将要显示的任何内容存储在上下文中。这样,抽屉只需要从上下文中检索其内容,并且需要设置内容的任何部分都可以直接通过上下文进行设置。

这是一个CodeSandbox 演示了这一点

关键代码片段:

const MainContent = () => {
  const items = ["foo", "bar", "biz"];

  const { setContent } = useContext(DrawerContentContext);
  /**
   * Note that in the real world, these components could exist at any level of nesting 
   */
  return (
    <Fragment>
      {items.map((v, i) => (
        <Button
          key={i}
          onClick={() => {
            setContent(<div>{v}</div>);
          }}
        >
          {v}
        </Button>
      ))}
    </Fragment>
  );
};

const MyDrawer = () => {
  const classes = useStyles();

  const { content } = useContext(DrawerContentContext); …
Run Code Online (Sandbox Code Playgroud)

reactjs react-context

7
推荐指数
1
解决办法
2915
查看次数

使用 React 测试库和 renderHook 测试具有多个上下文的钩子时出错

解决了

问题已在github上跟踪

试图使用反应测试库来测试自定义挂钩,并且我试图测试的挂钩需要多个上下文提供程序才能正常工作。(认证和通知)

这里的文档仅概述了使用单个提供程序创建包装器,如下所示:

const wrapper = ({ children }) => <ContextProvider>{children}</ContextProvider>
Run Code Online (Sandbox Code Playgroud)

但是,我的实现需要更复杂的东西,如下所示:

const wrapper = ({ children }) => (
    <ToastProvider>
        <NotificationProvider>
            <AuthProvider>{children}</AuthProvider>
        </NotificationProvider>
    </ToastProvider>
);
Run Code Online (Sandbox Code Playgroud)

每次尝试都失败并出现以下错误:

TypeError: parentInstance.children.indexOf is not a function
Run Code Online (Sandbox Code Playgroud)

或者

Invariant Violation: Drop(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.
Run Code Online (Sandbox Code Playgroud)

让我相信,如果不放弃 renderHook 并构建一个可以手动触发必要行为的测试组件,就没有明确的方法来提供正确的上下文。

经过更多挖掘后,我发现这个错误隐藏在日志中:

Warning: An invalid container has been provided. This may indicate that another renderer is being …
Run Code Online (Sandbox Code Playgroud)

reactjs jestjs react-context react-testing-library react-hooks

7
推荐指数
0
解决办法
3483
查看次数

防止子组件在上下文提供者下面重新渲染并带有备忘录

我在 React 中使用上下文提供程序来跨多个组件共享数据。然而,由于我的一个子组件的值发生了变化,它会重新渲染我的所有其他组件,这在一定程度上导致了性能问题。所以我想阻止我的子组件重新渲染。我尝试使用 React.memo() 但每当我设置 Context Provider 的状态时它仍然会呈现。

const Authenticator = React.memo(() => {
  
  const [myChat, setMyChat] = useContext(ChatContext);

  console.log("rerender"); // gets called everytime on click
  return (
    <Button
      title="click me"
      onPress={() => setMyChat({ text: "hello" })}
    ></Button>
  );
});
Run Code Online (Sandbox Code Playgroud)

我的上下文提供程序如下所示:

const ChatProvider = ({ children }) => {
  const [myChat, setMyChat] = useState([]);

  return (
    <ChatContext.Provider value={[myChat, setMyChat]}>
      {children}
    </ChatContext.Provider>
  );
};
Run Code Online (Sandbox Code Playgroud)

我的 App.js 如下所示:

<ChatProvider>
  <Authenticator />
</ChatProvider>
Run Code Online (Sandbox Code Playgroud)

memoization reactjs react-native react-context

7
推荐指数
1
解决办法
6477
查看次数