离子反应类型不可分配

问题描述

我正在使用带有以下代码的 ionic-react 及其给出的错误

输入'{状态:IState;调度:React.dispatch; }' 不可分配给类型 'IState'。 对象字面量只能指定已知的属性,而类型“IState”中不存在“state”。

代码如下

State.tsx

import React from "react";

export interface IState {
    count: number;
    loggedIn: boolean;
  }

// set the initial values
const initialState = { count: 0,loggedIn: false };

export type ActionType =
  | { type: "setLoggedIn"; payload: any }
  | { type: "error" };


// create the context
export const Context = React.createContext<IState>(initialState);

export const TheProvider = ({ children }: any): any => {
    /**
     * @param {*} state
     * @param {*} action
     */
    const reducer = (state: IState,action: ActionType): IState => {
      switch (action.type) {
        case "setLoggedIn":
          return { ...state,...action.payload };
        default:
          throw new Error();
      }
    };
  
    const [state,dispatch] = React.useReducer(reducer,initialState);
  
    // wrap the application in the provider with the initialized context
    return (
      <Context.Provider value={{ state,dispatch }}>{children}</Context.Provider>
    );
  };
  
  export default Context;

登录.tsx

import AppContext,{ TheProvider,IState }  from './State'; 


...

const Login: React.FC = () => {
    const { state,dispatch } = React.useContext<any>(AppContext);
  

    const doLogin = async () => {

        try{
          
           dispatch({
                type: 'setLoggedIn',payload: {loggedIn: false}
            })

        }catch(err){
          console.error("Failed to login with erro",err)
        }
      };

    return (
 <TheProvider>
        <form className="ion-padding">
        <IonToolbar>
          <IonTitle>Login</IonTitle>
        </IonToolbar>
          <IonItem style={{paddingTop:'100px'}}>
            <IonLabel position="floating">Email</IonLabel>
            <IonInput type="email" value={email} onIonChange={e => setEmail(e.detail.value!)}/>
          </IonItem>
          <IonItem>
            <IonLabel position="floating">Password</IonLabel>
            <IonInput type="password" value={password} onIonChange={e => setPassword(e.detail.value!)}/>
          </IonItem>
          <IonItem>
            <IonLabel>{errMessage}</IonLabel>
          </IonItem>
          
          <IonButton className="ion-margin-top" onClick={doLogin} expand="block">
            <IonIcon slot="start" icon={mailOutline} />Login
          </IonButton>
        </form>
        </TheProvider>
    )
};

我现在在发送时遇到错误

TypeError: dispatch 不是函数 在 doLogin

解决方法

问题在于这两行之间的差异:

export const Context = React.createContext<IState>(initialState);
// ...
<Context.Provider value={{ state,dispatch }}>

如果您希望您的上下文包含状态和分派,您需要将初始 Context 对象更改为如下所示:

interface ContextType {
    state: IState,dispatch?: React.Dispatch<ActionType>
  }
export const Context = React.createContext<ContextType>({ state: initialState });

在调用 useContext 时,您可以删除通用 <any>。然后您可能需要检查 dispatch 是否已定义,因为它在上面的 ContextType 中设置为可选:

import AppContext,{ TheProvider }  from './State'; 

// ...

const Login = () => {
  const { state,dispatch } = React.useContext(AppContext);

  const doLogin = async () => {
    if (dispatch === undefined) {
      return; // or display error message
    }
    try {
      dispatch({
        type: "setLoggedIn",payload: { loggedIn: false },});
    } catch (err) {
      console.error("failed to login with error:",err);
    }
  };

  return <div id="login"></div>; // presumably this holds your inputs,// submit button,forgot password link,etc.
}

然后,要确保上下文正确传递,您必须确保 LoginTheProvider 的子代。在同一个 Login.tsx 文件中,您可以像这样定义一个新组件 LoginPage,如果您有一个包含页眉、页脚、CSS 等的 Layout 组件:

const LoginPage = () => {
  return <TheProvider>
           <Layout>
             <h2>Please enter your information below to log in:</h2>
             <Login />
           </Layout>
         </TheProvider>
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...