web-dev-qa-db-ja.com

typescriptのreactフックでreactコンテキストを使用する

以下のコードは、反応フックを使用して反応のコンテキストを実装する方法を示しています。ここでのアイデアは、このような子コンポーネントからコンテキストに簡単にアクセスできるようになるということです。

const {authState, authActions} = useContext(AuthCtx);

まず、コンテキストとプロバイダーをエクスポートするファイルを作成します。

import * as React from 'react';

const { createContext, useState } = React;

const initialState = {
  email: '',
  password: ''
};

const AuthCtx = createContext(initialState);

export function AuthProvider({ children }) {
  function setEmail(email: string) {
    setState({...state, email});
  }

  function setPassword(password: string) {
    setState({...state, password}); 
  }

  const [state, setState] = useState(initialState);
  const actions = {
    setEmail,
    setPassword
  };

  return (
    <AuthCtx.Provider value={{ authState: state, authActions: actions }}>
      {children}
    </AuthCtx.Provider>
  );
}

export default AuthCtx;

これは機能しますが、以下のプロバイダーのvalueでエラーが発生します。おそらくアクションを追加したためです。したがって、質問は、すべての入力を維持し、コンテキストとプロバイダーをエクスポートできる方法はありますか?

また、createContextをメイン関数に配置できないので、常に再作成されます。

[ts]タイプ '{authState:{email:string;パスワード:文字列; }; authActions:{setEmail:(email:string)=> void; setPassword:(password:string)=> void; }; } 'はタイプ' {email:string;に割り当てることができません。パスワード:文字列; } '。オブジェクトリテラルは既知のプロパティのみを指定でき、 'authState'はタイプ '{email:string;には存在しません。パスワード:文字列; } '。 [2322] index.d.ts(266、9):予期されるタイプは、ここでタイプ 'IntrinsicAttributes&ProviderProps <{email:string;で宣言されているプロパティ' value 'からのものです。パスワード:文字列; }> '(プロパティ)authState:{email:string;パスワード:文字列; }

6
Ilja

コンテキストの作成中に、初期値を提供します。プロバイダーのように期待するのと同じ形式で提供します。

const initialState = {
  authState : { 
      email: '',
      password: ''
  },
  authActions = {
    setEmail: () => {},
    setPassword: () => {}
  };
};

const AuthCtx = createContext(initialState);

また、コンシューマの階層の上位にプロバイダがない場合、consumerに渡されるだけなので、initialStateも必要ありません。

3
Shubham Khatri