Я новичок в 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;
};
Скриншот ошибки:
const [history, setHistory] = React.useState()
Поскольку здесь не указан тип, машинописный текст должен попытаться его вывести. Он видит, что undefined
неявно передается в состояние использования, поэтому предполагает, что это состояние (и всегда будет) undefined
. Это означает, что setHistory
ожидает прохождения undefined
.
Вам нужно будет указать тип самостоятельно, чтобы сказать, что он может быть либо числом, либо неопределенным:
const [history, setHistory] = React.useState<number | undefined>();
Или, если это всегда должно быть число, вы тоже можете это сделать, но вам нужно будет указать начальное значение, которое является числом:
const [history, setHistory] = React.useState<number>(42);
P.S: Это не имеет отношения к вашему вопросу, но я заметил, что этот код использует распространенную ошибку: вы создаете новый объект при каждом рендеринге и передаете его в качестве значения контекста.
value = {{ history, setHistory }}>
Поскольку при каждом рендеринге появляется новое значение, это заставит все, что использует контекст, перерендериться, даже если история и setHistory не изменились. Чтобы исправить это, вы должны запомнить значение, чтобы оно пересчитывалось только тогда, когда оно действительно изменяется:
const value = React.useMemo(() => {
return { history, setHistory };
}, [history]);
return (
<HistoryContext.Provider value = {value}>
{children}
</HistoryContext.Provider>
);
Спасибо Николай за решение. Я также изменил код и включил useMemo.