首页 > 解决方案 > 使用 context api 和 HOC 的不同组件的状态不会更新

问题描述

我正在尝试使用上下文 api 更新应用程序的状态,因为我不需要 redux 的所有功能,也不想处理道具钻孔。因此,我使用 typescript 创建了一个全局上下文和一个包装组件的 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;

这是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;

这是提供者。

大多数类都包装在 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), …}

组件在根视图中调用 dispatch 后更新,但在另一个类中更新状态后,它不会在其他类中更新。

标签: javascriptreactjstypescript

解决方案


按照您现在设置的方式,使用 HOC 的组件的每个实例都有自己的GlobalProvider实例,因此也有自己独立的“全局”状态。尝试GlobalProvider从 HOC 中移除,而是在组件树的最外层添加单个GlobalProvider组件。


推荐阅读