简体   繁体   English

使用上下文api和HOC不会为不同组件更新状态

[英]The state doesn't update for different components using context api and HOC

I'm trying to update the state of the application using the context api since I don't need all of the features of redux and I don't want to deal with prop drilling. 我正在尝试使用上下文api更新应用程序的状态,因为我不需要redux的所有功能,并且我也不想处理prop钻探。 So with typescript I made a global context and a HOC wrapper that wraps the component so the component class can have access to the context. 因此,使用打字稿,我创建了一个全局上下文和一个用于包装组件的HOC包装器,以便组件类可以访问该上下文。

import * as React from 'react';

import GlobalConsumer from './globalConsumer';
import GlobalProvider from './globalProvider';
import IGlobalState from './globalState';

type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
type Subtract<T, K> = Omit<T, keyof K>;

export interface IInjectWithState {
  globalState: IGlobalState;
}

const withState = <P extends IInjectWithState>(
  Component: React.ComponentType<P>
): React.ComponentType<Subtract<P, IInjectWithState>> =>
  class WithState extends React.Component<Subtract<P, IInjectWithState>> {
    public render(): JSX.Element {
      return (
        <GlobalProvider>
          <GlobalConsumer>
            {state => <Component {...this.props} globalState={state} />}
          </GlobalConsumer>
        </GlobalProvider>
      );
    }
  };

export default withState;

This is the HOC. 这就是HOC。

import * as React from 'react';

import reducer from './reducer';

import IGlobalState from './globalState';

import GlobalContext, { initState } from './globalContext';

class GlobalProvider extends React.Component<{}, IGlobalState> {
  constructor(props: any) {
    super(props);
    this.state = {
      ...initState,
      dispatch: (action: object) =>
        this.setState(() => {
          return reducer(this.state, action);
        })
    };
  }

  public render(): JSX.Element {
    return (
      <GlobalContext.Provider value={this.state}>
        {this.props.children}
      </GlobalContext.Provider>
    );
  }
}

export default GlobalProvider;

This is the provider. 这是提供者。

Most classes are wrapped in the HOC, but whenever I call dispatch and change the state in one of the component classes, the global state doesn't update in the other component classes. 大多数类都包装在HOC中,但是每当我调用dispatch并更改其中一个组件类的状态时,全局状态不会在其他组件类中更新。

  RootView.tsx:35 
{appBarTitle: "Welcome", canContinue: true, currentPage: Array(0), dispatch: ƒ, nextPage: Array(0), …}
    ContinueButton.tsx:31 
{appBarTitle: "Welcome", canContinue: true, currentPage: Array(0), dispatch: ƒ, nextPage: Array(0), …}
    RootView.tsx:39 
{appBarTitle: "Welcome", canContinue: true, currentPage: Array(1), dispatch: ƒ, nextPage: Array(1), …}
    Start.tsx:21 
{appBarTitle: "Welcome", canContinue: true, currentPage: Array(0), dispatch: ƒ, nextPage: Array(0), …}
    ContinueButton.tsx:35 
{appBarTitle: "Welcome", canContinue: true, currentPage: Array(0), dispatch: ƒ, nextPage: Array(0), …}

The component is updated after calling dispatch in the root view, but after updating the state in another class, it doesn't update in the others. 在根视图中调用dispatch之后,该组件会更新,但是在另一个类中更新状态后,其他类不会更新。

The way you have it set up now, each instance of a component that uses the HOC has its own GlobalProvider instance and thus its own independent "global" state. 现在设置的方式,使用HOC的组件的每个实例都具有自己的GlobalProvider实例,因此具有自己的独立“全局”状态。 Try removing GlobalProvider from the HOC and instead adding a single GlobalProvider component at the outermost level of your component tree. 尝试从HOC中删除GlobalProvider ,而在组件树的最外层添加一个GlobalProvider组件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM