【问题标题】:How can I use the context provider api and typescript without correcting me all the time如何在不一直纠正我的情况下使用上下文提供程序 api 和 typescript
【发布时间】:2021-12-29 16:09:06
【问题描述】:

下面的代码向我抛出了错误:

frontend_1  | TypeScript error in /frontend/src/State/Store.tsx(23,27):
frontend_1  | Property 'test' is missing in type 'any[]' but required in type '{ test: string; }'.  TS2741
frontend_1  | 
frontend_1  |     21 | 
frontend_1  |     22 |     return (
frontend_1  |   > 23 |         <Context.Provider value={[state, dispatch]}>
frontend_1  |        |                           ^
frontend_1  |     24 |             {children}
frontend_1  |     25 |         </Context.Provider>
frontend_1  |     26 |     )
import { createContext, useReducer } from "react";

const initialState = {
    test: "text-string"
}


const reducer = (state: any, action: any): any => {
    switch (action.type) {
        case 'SET_PUBLIC_KEY':
            return {
                ...state,
            }
        default:
            return state;
    }
};

function Store({ children }: any) {
    const [state, dispatch] = useReducer(reducer, initialState);

    return (
        <Context.Provider value={[state, dispatch]}>
            {children}
        </Context.Provider>
    )
};

export const Context = createContext(initialState);
export default Store;

我试图修复它几个小时,但无论我尝试了什么,它仍然给我同样的错误。如果有人可以帮助我,我将不胜感激。这个例子在普通的 javascript 中工作就像一个魅力,所以问题只出现在 typescript 上。

提前致谢!

【问题讨论】:

  • 您的意思是&lt;Context.Provider value={state}&gt;?上下文类型是{test: string},但您试图传递一个无效的两个元素数组 ([{test: string}, (...) =&gt; ...])。您要么需要将state 作为上下文值传递,要么更改上下文的类型:createContext([initialState, () =&gt; initialState] as const)
  • 我实际上想在所有子元素中使用调度功能。我是打字稿的新手,我仍然很难理解完整的概念。我真的很想通过,因为它似乎有一些主要的优势。但是它阻碍了我的工作效率:) @Ramesh Reddy 为我解决了非常感谢!

标签: reactjs typescript state react-context


【解决方案1】:

传递给提供者的value(具有状态和分派的数组)的类型和传递给createContextinitialState(只是状态)的类型是不同的。只需确保这两个值的类型相同即可。

您可以为减速器的状态、动作定义接口并在任何地方使用它们。

interface State {
  test: string;
}

interface Action {
  type: string;
  payload?: any; // update this as you like
}

const initialState = {
  test: "text-string"
};

const reducer = (state: State, action: Action) => {
  switch (action.type) {
    case "SET_PUBLIC_KEY":
      return {
        ...state,
        test: "modifed"
      };
    default:
      return state;
  }
};

// passing an array that matches the type of context's value
export const Context = createContext<[State, Dispatch<Action>]>([
  initialState,
  () => initialState
]);

function Store({ children }: any) {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <Context.Provider value={[state, dispatch]}>{children}</Context.Provider>
  );
}

const Child = () => {
  const [state, dispatch] = useContext(Context);

  return (
    <div onClick={() => dispatch({ type: "SET_PUBLIC_KEY" })}>{state.test}</div>
  );
};

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <Store>
        <Child />
      </Store>
    </div>
  );
}

【讨论】:

    猜你喜欢
    • 2021-08-20
    • 2021-06-09
    • 2022-08-23
    • 1970-01-01
    • 2020-11-06
    • 2022-06-30
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多