reactjs - PrevState-typing i TypeScript
Jeg bruker en kontekst for å lagre et objekt for dialogen min. Jeg har en funksjon som oppdaterer et array lagret i konteksten basert på prevState, men TypeScript liker ikke typingen min av prevState.
Argument av typen '(prevState: SourceOrganizationAccount[]) => SourceOrganizationAccount[]' kan ikke tildeles til parameter av typen 'SourceOrganizationAccount[]'. Typen '(prevState: SourceOrganizationAccount[]) => SourceOrganizationAccount[]' mangler følgende egenskaper fra typen 'SourceOrganizationAccount[]': pop, push, concat, join, og 27 til.
Her er min komponent med funksjonen handleCheckAccountDetailsClick. Den klager på denne linjen sourceOrganizationAccounts.setValue((prevState: SourceOrganizationAccount[]) => {. Hva er galt med det prevState?
import React from 'react';
import { getAccount } from 'utils';
import {
SourceOrganizationAccount,
useImportAccountsContext,
} from '../ImportAccountsContext';
export function ImportAccountsTable() {
const { sourceOrganizationAccounts } = useImportAccountsContext();
async function handleCheckAccountDetailsClick(account: SourceOrganizationAccount) {
const accountDetailsRes = await getAccount();
if (accountDetailsRes.success) {
sourceOrganizationAccounts.setValue((prevState: SourceOrganizationAccount[]) => {
const updatedArray = prevState.map(sourceOrganizationAccount => {
return sourceOrganizationAccount.locator === account.locator
? {
...sourceOrganizationAccount,
...accountDetailsRes.accountDetails,
}
: sourceOrganizationAccount;
});
return updatedArray;
});
}
}
return <>Test</>;
}
Mine typer
export type SourceOrganizationAccount = {
name: string;
createdOn: number;
locator: string;
}
export interface StateVariable<T> {
value: T;
setValue: (value: T) => void;
}
export interface ImportAccountsState {
sourceOrganizationAccounts: StateVariable<SourceOrganizationAccount[]>;
}
const ImportAccountsContext = createContext<ImportAccountsState>(
{} as ImportAccountsState,
);
export const ImportAccountsProvider = ({ children }: props) => {
const [sourceOrganizationAccounts, setSourceOrganizationAccounts] = useState<
SourceOrganizationAccount[]
>([]);
const resetContext = useCallback(() => {
setSourceOrganizationAccounts([]);
}, [
setSourceOrganizationAccounts,
]);
const initialState: ImportAccountsState = {
sourceOrganizationAccounts: {
value: sourceOrganizationAccounts,
setValue: setSourceOrganizationAccounts,
}
};
return (
<ImportAccountsContext.Provider value={initialState}>
{children}
</ImportAccountsContext.Provider>
);
};
export const useImportAccountsContext = () => {
return useContext<ImportAccountsState>(ImportAccountsContext);
};
Svar #1
Hvis du sjekker grundig typen din StateVariable<T>, kan du legge merke til at setValue-feltet av den typen har signatur:
setValue: (value: T) => void
Mens du prøver å mate det med en verdi av typen T i stedet for verdien (funksjonen) av typen: (prevState: T) => T.
For å matche implementeringen av funksjonen din bør typen StateVariable defineres som:
interface StateVariable<T> {
value: T;
setValue: (cb: (value: T) => T) => void;
}
React eksponerer spesielle hjelpe-typer for typing av useState dispatch-funksjoner: Dispatch<SetStateAction<T>> slik at du også kan skrive det som:
import { Dispatch, SetStateAction } from 'react'
interface StateVariable<T> {
value: T
setValue: Dispatch<SetStateAction<T>>
}
