标签: react-context

使用 HOC 访问 Next.js getInitialProps 中消耗的 React.Context

我试图通过使用一个简单的服务来抽象我的 API 调用,该服务提供了一个非常简单的方法,这只是一个 HTTP 调用。我将此实现存储在 React Context 中,并在 my 中使用其提供程序_app.js,以便该 API 全局可用,但我在实际使用页面中的上下文时遇到问题。

页面/_app.js

import React from 'react'
import App, { Container } from 'next/app'

import ApiProvider from '../Providers/ApiProvider';

import getConfig from 'next/config'
const { serverRuntimeConfig, publicRuntimeConfig } = getConfig()

export default class Webshop extends App 
{
    static async getInitialProps({ Component, router, ctx }) {
        let pageProps = {}

        if (Component.getInitialProps) {
            pageProps = await Component.getInitialProps(ctx)
        }

        return { pageProps }
    }

    render () {
        const { Component, pageProps …
Run Code Online (Sandbox Code Playgroud)

javascript reactjs next.js react-context

5
推荐指数
1
解决办法
1万
查看次数

渲染为带有上下文的字符串?

我有一个组件(EmailBuilder),它使用react context api来渲染一些东西,我想将其渲染为html,我尝试了这个:

import * as React from 'react'
import { EmailBuilder } from './EmailBuilder';
import ReactDOMServer from 'react-dom/server';

export const EmailBuilderPage = (props: any) => {
    const element = <EmailBuilder />
    return <>
        {element}

        <br />
        <h1>HTML</h1>
        {ReactDOMServer.renderToString(element)}
    </>
}
Run Code Online (Sandbox Code Playgroud)

虽然渲染了元素的根,但它无法渲染上下文 api 对元素的任何更改。

这可能吗?

reactjs react-dom react-context

5
推荐指数
0
解决办法
569
查看次数

React 上下文是否应该始终是单例,还是有其他方法?

我见过的React上下文的每个例子都是这样

theme-context.js

// Make sure the shape of the default value passed to
// createContext matches the shape that the consumers expect!
export const ThemeContext = React.createContext({
  theme: themes.dark,
  toggleTheme: () => {},
});
Run Code Online (Sandbox Code Playgroud)

您的文件包含上下文的实例。然后使用将其传递到组件中useContext(ThemeContext)

我的问题是,如果你这样做并且它始终是单例,那么为什么不直接从单例导入上下文中的内容呢?基本上我想知道是否有一次您创建了多个上下文实例,例如为了测试,您可能会在每次测试时创建一个新实例,类似的事情。

reactjs react-context

5
推荐指数
1
解决办法
3152
查看次数

React Context:从 API 获取数据并在 React 组件中发生某些事件时调用 API

我是 React Context 的新手。我需要在 React 上下文中调用 API,以便在整个 React 应用程序中使用其数据。此外,还需要对 React 应用程序的各个组件上的某些 CRUD 操作调用相同的 API。

现在我将 API 数据存储在 redux 中,但我不想存储它。

这是我尝试过的..

context.js 文件

import React, { useState, createContext,useEffect } from 'react';
import {getData} from './actionMethods';

const NewContext = createContext();

function newContextProvider(props) {
    useEffect(async () => {
         const {dataValue}  = await getData()

         console.log("Data " , dataValue)    
     }, [])
     
     return (
        <NewContext.Provider
            value={{
                state: {
                    
                },
                actions: {
                    
                }
            }}
        >
            {props.children}
        </NewContext.Provider>
    );
}


const newContextConsumer = newContext.Consumer;

export { newContextProvider, newContextConsumer, …
Run Code Online (Sandbox Code Playgroud)

javascript reactjs react-context react-hooks

5
推荐指数
1
解决办法
5236
查看次数

如何更改功能组件中的上下文值?

我有一个StatusContext这样命名的上下文:

export const statusCtxInit = {
    open: false,
    toggleOpen() {
        this.open = !this.open;
    }
};

const StatusContext = React.createContext(statusCtxInit);
export default StatusContext
Run Code Online (Sandbox Code Playgroud)

整个应用程序都与提供者一起包装:

// ...
<StatusContext.Provider value={statusCtxInit}>
// ...
Run Code Online (Sandbox Code Playgroud)

useContext为了使用我在 FC 中使用的上下文的值,当我获得该值时它就会起作用。

function MyComp() {
    const status = useContext(StatusContext);
    return (
        <div>
            {status.open
                ? `It's Open`
                : `It's Closed`}

            <button onClick={() => status.toggleOpen()}>
                Toggle
            </button>
        </div>
    )
}

export default MyComp
Run Code Online (Sandbox Code Playgroud)

另一方面,我也想通过调用来更改上下文toggleOpen,但是它不能按我想要的方式工作。实际上该值发生变化但不影响MyComp.

我做错了什么?我该怎么办?

reactjs react-context react-functional-component

5
推荐指数
1
解决办法
3927
查看次数

React Context 未将类更新为值

我有一个使用类实例作为上下文值的上下文。在我更新了类实例之后。这种变化不会反映在消费者身上。消费者仍然可以获得旧类别的价值。有人可以指出我如何实现这一目标的方向吗?

// Service class
class Service {
   name = "oldName"
   function changeName(newName){
       this.name = newName;
   }
}

//Context provider
function App() {
  const service = new Service();
  return (
    <ServiceContext.Provider value={service}>
      <Home />
    </ServiceContext.Provider>
  );
}
Run Code Online (Sandbox Code Playgroud)

然后我尝试在一个组件中更改此服务的名称属性。

import React, { useContext } from "react";

const SomeComponent = () => {
  const service = useContext(ServiceContext);
  const onClick = () => {
    service.changeName('newName')
    console.log(service.name) //here the name has updated
  }
  return <button onClick={onClick}>Change</h1>;
};

Run Code Online (Sandbox Code Playgroud)

并尝试从组件中获取更新后的值。

import React, { useContext } from "react"; …
Run Code Online (Sandbox Code Playgroud)

reactjs react-context

5
推荐指数
1
解决办法
1702
查看次数

如何为以下 contextapi 代码设置 useReducer useContext 的 Typescript 类型?

我想在下面的代码中使用正确的 TS 类型,而不是任何类型。我是反应 TS 的新手,请帮助...

如何为以下上下文 API 代码设置 useReducer useContext 的打字稿类型:

import React, {createContext, Dispatch} from 'react';
import {firebaseUser} from '../@types/User';

interface Actions {
  SET_IMAGENAME: string;
  SET_USER: string;
}

export const Actions: Actions = {
  SET_IMAGENAME: 'SET_IMAGENAME',
  SET_USER: 'SET_USER',
};

function action(type: string) {
  return {type};
}

function actionPayload(type: string, payload: any) { //here
  return {type, payload};
}

export const Dispatches = {
  setImageName: action,
  setUser: actionPayload,
};

interface State {
  imgName: string;
  user: firebaseUser;
}

const initialState = { …
Run Code Online (Sandbox Code Playgroud)

typescript reactjs react-context react-typescript use-reducer

5
推荐指数
1
解决办法
2853
查看次数

如何在不渲染任何组件的函数中使用 React.useContext ?

我需要获取在特定事件上调用的函数内而不是渲染器内的上下文的当前值。

例子:

logCurrentTheme.js

import React, { useContext } from 'react';
import {ThemeContext} from "./ThemeContext";
// ThemeContext is a context created by React.createContext()

function logCurrentTheme() {
  const context = useContext(ThemeContext);
  console.log(context.themeColor)
}
export {logCurrentTheme};
Run Code Online (Sandbox Code Playgroud)

在我的其他一些组件中

//...
import {logCurrentTheme} from "./logCurrentTheme.js";
//...
const someComponent () => {
  return(
    <Button onClick={logCurrentTheme} title="Log Current Theme"/>
  );
}
Run Code Online (Sandbox Code Playgroud)

上面的例子编译成功,但是一旦单击按钮就会抛出错误:

无效的挂钩调用。钩子只能在函数组件体内调用

我知道这是一个“函数”而不是“函数组件”。但我还能怎样做呢?

编辑:

基于@tudor's 答案的工作示例

LogContextButton.js

import React from "react";
import { useContextHelper } from "./ContextHelper";

export const LogContextButton = props => {
  var { logCurrentContextValue …
Run Code Online (Sandbox Code Playgroud)

reactjs react-context

5
推荐指数
1
解决办法
1万
查看次数

库中的反应上下文未在消费者中更新

我最初关注这个项目是为了将 Firebase 添加到 Gatsby React 应用程序中。它涉及创建 Firebase 上下文,使用提供者包装根布局,然后使用 withFirebase HOC 根据需要使用 Firebase 使用者包装组件。当我最初这样做时,它工作得很好,但我想将代码移动到一个可以在我的应用程序中重用的包中。这是 HOC

export const withFirebase = (Component) => (props) => (
  <FirebaseContext.Consumer>
    {(firebase) => <Component {...props} firebase={firebase} />}
  </FirebaseContext.Consumer>
);
Run Code Online (Sandbox Code Playgroud)

每个页面都以一个呈现以下内容的布局组件开始:

<FirebaseContext.Provider value={this.state.firebase}>
  <AppWithAuthentication>
    {this.props.children}
  </AppWithAuthentication>
</FirebaseContext.Provider>
Run Code Online (Sandbox Code Playgroud)

AppWithAuthentication它本身使用withFirebaseHOC,因为它需要 Firebase 来获取 AuthUser(然后将其存储在上下文中并通过提供者传递),并且它能够很好地做到这一点。

上述所有情况都发生在包代码本身中,但是当我将包导入到其他 React 项目中时,尝试使用 usewithFirebase停止工作,因为用它包装的任何组件都不会收到更新的上下文。我通过检查 React Dev 工具中的组件树来确认这一点,Firebase Provider 获取更新的非空值,内部的使用者AppWithAuthentication也获取它。但我的实际应用程序内的消费者不会更新(并且我在同一库中创建的 AuthUser 上下文也有同样的问题)。

我什至认为,也许父级正在使用更新后的消费者进行渲染,但子级没有重新渲染,但在计算渲染并记录它们之后,很明显,我的应用程序中的组件渲染的次数比AppWithAuthentication. 为了让它更清楚一点,这是我的组件树(从页面根目录的布局组件开始):
组件树

这是 Provider 显示的值:
有价值的提供者

这是AppWithAuthentication消费者显示的值:
有价值的消费者

这是我的应用程序内部没有值的消费者:
没有价值的消费者

我完全被困在这里,希望得到任何见解。

编辑:经过更多测试后,我发现了更多信息,但我仍然陷入困境。看起来,当重新加载我的页面时,该Layout组件呈现 …

reactjs webpack react-context

5
推荐指数
1
解决办法
1855
查看次数

如何在React中不同组件库之间共享上下文?

在 React 中,有一种简单的方法可以在多层组件中共享“信息”。这是通过使用上下文

import {UserCtx} from "./stores/UserCtx"; 
<UserCtx.Provider value={new user(info)}>
    <SomeComponent />
</UserCtx.Provider/>
Run Code Online (Sandbox Code Playgroud)

然后在某个组件中:

import {UserCtx} from "./stores/UserCtx";
function SomeComponent() {
    const userData = React.useContext(UserCtx);
    return <div>JSON.stringify(userData)</div>
}
Run Code Online (Sandbox Code Playgroud)

然而,这要求上下文对象定义对于所有对象都是可见的。因此,当创建组件库时,它不能真正被使用吗?

假设上面的“示例”SomeComponent是一个库组件,我如何将主应用程序的上下文共享给该组件?通过添加属性来共享似乎有些牵强,在这一点上我不妨直接提供用户(或上下文存储的任何内容)?

javascript reactjs react-component react-context

5
推荐指数
1
解决办法
2529
查看次数