为了账号安全,请及时绑定邮箱和手机立即绑定

Typescript React createContext 和 useState

Typescript React createContext 和 useState

Qyouu 2023-11-02 19:56:19
我是 TS 的新手,正在尝试更新我从前员工那里继承的代码。我知道它与 TS 相关,并且尝试了不同类型但无法解决它。任何帮助都会很棒。提前致谢。这是代码:import React from 'react';export interface HistoryType {  history?: number;  setHistory: (value: number) => void;}const HistoryContext = React.createContext<HistoryType | undefined>(undefined);export const HistoryProvider: React.FC = ({ children }) => {  const [history, setHistory] = React.useState();  return (    <HistoryContext.Provider value={{ history, setHistory}}>      {children}    </HistoryContext.Provider>  );};export const useHistoryState = () => {  const context = React.useContext(HistoryContext);  if (context === undefined) {    throw new Error('useHistoryState error');  }  return context;};错误截图:https://i.stack.imgur.com/YKbri.png
查看完整描述

1 回答

?
ibeautiful

TA贡献1993条经验 获得超5个赞

const [history, setHistory] = React.useState()

由于此处未指定类型,因此打字稿必须尝试推断它。它看到undefined被隐式传递给 use state,因此它假设状态是(并且永远是)undefined。那么这意味着setHistory期望能够通过undefined。


您需要自己指定类型,以表示它可以是数字,也可以是未定义的:


const [history, setHistory] = React.useState<number | undefined>();

或者,如果它始终应该是一个数字,您也可以这样做,但您需要提供一个数字的初始值:


const [history, setHistory] = React.useState<number>(42);

PS:这与您的问题无关,但我注意到这段代码使用了一个常见错误:您在每次渲染上创建一个全新的对象并将其作为上下文值传递。


value={{ history, setHistory }}>

由于每次渲染都有一个新值,因此即使历史记录和 setHistory 没有更改,它也会强制消耗上下文的任何内容重新渲染。要解决此问题,您应该记住该值,以便仅在实际更改时重新计算它:


  const value = React.useMemo(() => {

    return { history, setHistory };

  }, [history]);


  return (

    <HistoryContext.Provider value={value}>

      {children}

    </HistoryContext.Provider>

  );


查看完整回答
反对 回复 2023-11-02
  • 1 回答
  • 0 关注
  • 62 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信