【问题标题】:Typescript for React createContext and useContextReact createContext 和 useContext 的打字稿
【发布时间】:2019-06-07 23:08:48
【问题描述】:

我有一个带有状态 Provider 的 React Context 文件来管理 cookie 首选项。这一切都按预期工作,但我在使用 Typescript 时遇到了 1 个问题。我的文件如下所示:

import Cookies from 'js-cookie';
import React, { Component, ReactNode } from 'react';

interface Props {
  children: ReactNode | ReactNode[];
  functionalCookiesOn: boolean;
  performanceCookiesOn: boolean;
};

interface State {
  functionalCookiesOn: boolean;
  performanceCookiesOn: boolean;
};

// Initialise context storage
const CookiesContext = React.createContext({});
const { Consumer: CookiesConsumer } = CookiesContext;

class CookiesProvider extends Component<Props, State> {
  constructor(props: Props) {
    super(props);

    const {
      functionalCookiesOn,
      performanceCookiesOn,
    } = this.props;

    this.state = {
      functionalCookiesOn,
      performanceCookiesOn,
    };
  }

  componentDidUpdate(_prevProps: Props, prevState: State) {
    const {
      functionalCookiesOn,
      performanceCookiesOn,
    } = this.state;

    // Set cookie to store functional cookies setting
    if (functionalCookiesOn !== prevState.functionalCookiesOn) {
      Cookies.set('functionalCookiesOn', functionalCookiesOn.toString());
    }

    // Set cookie to store performance cookies setting
    if (performanceCookiesOn !== prevState.performanceCookiesOn) {
      Cookies.set('performanceCookiesOn', performanceCookiesOn.toString());
    }
  }

  toggleAllCookies = () => {
    // Store reversed state for functional and performance cookies
    this.setState((prevState: State) => ({
      functionalCookiesOn: !prevState.functionalCookiesOn,
      performanceCookiesOn: !prevState.performanceCookiesOn,
    }));
  }

  render() {
    const { children } = this.props;

    const {
      functionalCookiesOn,
      performanceCookiesOn,
    } = this.state;

    const value = {
      functionalCookiesOn,
      performanceCookiesOn,
      toggleAllCookies: this.toggleAllCookies,
    };

    return (
      <CookiesContext.Provider value={value}>
        {children}
      </CookiesContext.Provider>
    );
  }
}

export default CookiesContext;
export { CookiesConsumer, CookiesProvider };

当我在另一个函数组件中使用它时,它看起来像这样:

const AnotherComponent = () => {
  const {
    functionalCookiesOn,
    performanceCookiesOn,
    toggleAllCookies,
  } = useContext(CookiesContext);

  return (
    ...
  );
}

这会引发错误,例如:

Property 'functionalCookiesOn' does not exist on type '{}'.

在我看来,这与原始文件中的以下行有关:

const CookiesContext = React.createContext({});

因为我用一个空对象初始化上下文(因为在那个阶段它没有值)。

初始化 this 或应用类型以避免此错误的正确方法是什么?

【问题讨论】:

  • 是的,您需要提供初始值。否则打字稿会抛出错误

标签: javascript reactjs typescript


【解决方案1】:

我认为您可以在致电createContext 时提供一个类型

const CookiesContext = React.createContext<Partial<Props>>({});

&lt;Partial&gt; 允许您创建没有默认值的上下文。

【讨论】:

  • 对了。我认为这几乎就在那里,尽管我认为 Props 或 State 接口使用不正确,因为我也将 toggleAllCookies 方法传递给了 Provider。我应该为此创建一个新界面吗?
  • 这个页面是一个很好的指南:fettblog.eu/typescript-react/context
  • 啊,完美,他们的示例为它创建了一个新界面。太好了,谢谢!
【解决方案2】:

试试这个;-

import Cookies from 'js-cookie';
import React, { Component, ReactNode } from 'react';

interface Props {
  children: ReactNode | ReactNode[];
  functionalCookiesOn: boolean;
  performanceCookiesOn: boolean;
};

interface State {
  functionalCookiesOn: boolean;
  performanceCookiesOn: boolean;
};

// Initialise context storage
const CookiesContext = React.createContext({
    functionalCookiesOn: false,
    performanceCookiesOn: false,
    toggleAllCookies: () => null
});
const { Consumer: CookiesConsumer } = CookiesContext;

class CookiesProvider extends Component<Props, State> {
  constructor(props: Props) {
    super(props);

    const {
      functionalCookiesOn,
      performanceCookiesOn,
    } = this.props;

    this.state = {
      functionalCookiesOn,
      performanceCookiesOn,
    };
  }

  componentDidUpdate(_prevProps: Props, prevState: State) {
    const {
      functionalCookiesOn,
      performanceCookiesOn,
    } = this.state;

    // Set cookie to store functional cookies setting
    if (functionalCookiesOn !== prevState.functionalCookiesOn) {
      Cookies.set('functionalCookiesOn', functionalCookiesOn.toString());
    }

    // Set cookie to store performance cookies setting
    if (performanceCookiesOn !== prevState.performanceCookiesOn) {
      Cookies.set('performanceCookiesOn', performanceCookiesOn.toString());
    }
  }

  toggleAllCookies = () => {
    // Store reversed state for functional and performance cookies
    this.setState((prevState: State) => ({
      functionalCookiesOn: !prevState.functionalCookiesOn,
      performanceCookiesOn: !prevState.performanceCookiesOn,
    }));
  }

  render() {
    const { children } = this.props;

    const {
      functionalCookiesOn,
      performanceCookiesOn,
    } = this.state;

    const value = {
      functionalCookiesOn,
      performanceCookiesOn,
      toggleAllCookies: this.toggleAllCookies,
    };

    return (
      <CookiesContext.Provider value={value}>
        {children}
      </CookiesContext.Provider>
    );
  }
}

export default CookiesContext;
export { CookiesConsumer, CookiesProvider };

这应该可以解决问题,打字稿将启动智能感知。

【讨论】:

    猜你喜欢
    • 2019-12-15
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-05
    • 2019-04-24
    • 2013-12-29
    • 1970-01-01
    相关资源
    最近更新 更多