[英]i have react custom hook error with typescript
I have this error in VScode: Argument of type 'Animal[]' is not assignable to parameter of type 'string'.我在 VScode 中有这个错误:'Animal[]' 类型的参数不可分配给'string' 类型的参数。 my custom hook file(useLocalHost.tsx) is:
我的自定义挂钩文件(useLocalHost.tsx)是:
import React, { useState, useEffect, SetStateAction, Dispatch } from "react";
import { Animal } from "@frontendmasters/pet";
function getSavedValue(key: string, initialValue: string) {
const savedValue = JSON.parse(localStorage.getItem(key) || '{}');
if (savedValue) {
return savedValue;
}
return initialValue;
}
export default function useLocalStorage(key: string, initialValue: string) {
const [value, setValue] = useState(() => {
return getSavedValue(key, initialValue);
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [value]);
return [value, setValue] as [Animal[], Dispatch<SetStateAction<Animal[] | null>>];
}
my search file (searchParams.tsx) is:我的搜索文件(searchParams.tsx)是:
import React, { useState, useEffect, useContext, FunctionComponent } from "react";
import pet, { ANIMALS, Animal } from "@frontendmasters/pet";
import useDropdown from "./useDropdown";
import { RouteComponentProps } from '@reach/router';
import SearchResult from "./SearchResult";
import useLocalStorage from "./useLocalStorage";
import ThemeContext from "./ThemeContext";
const SearchParams: FunctionComponent<RouteComponentProps> = () => {
const [location, updateLocation] = useState("Seattle, WA");
const [breeds, updateBreeds] = useState([] as string[]);
const [pets, updatePets] = useState([] as Animal[]);
const [animal, AnimalDropdown] = useDropdown("Animal", "dog", ANIMALS);
const [breed, BreedDropdown, updateBreed] = useDropdown("Breed", "", breeds);
const [prevPet, setPrevPet] = useLocalStorage([] as Animal[], "");
const [theme, setTheme] = useContext(ThemeContext);
async function requestPets() {
const { animals } = await pet.animals({
location,
breed,
type: animal,
});
setPrevPet(animals);
updatePets(animals || []);
}
useEffect(() => {
updateBreeds([]);
updateBreed("");
pet.breeds(animal).then(({ breeds }) => {
const breedStrings = breeds.map(({ name }) => name);
updateBreeds(breedStrings);
}, console.error);
}, [animal]);
useEffect(() => {
updatePets(prevPet);
}, []);
I know that the error comes from the type of prevPet put I don't know what type it should be there is more in searchParams.tsx but I think it's not needed我知道错误来自 prevPet 的类型我不知道它应该是什么类型 searchParams.tsx 中有更多但我认为不需要
Your getSavedValue
function has bugs in it.您的
getSavedValue
function 中有错误。
const savedValue = JSON.parse(localStorage.getItem(key) || '{}');
I think this should be我认为这应该是
const savedValue = JSON.parse(localStorage.getItem(key) || {});
Otherwise the return type of your function can be an object or a string (when nothing was in the storage).否则,您的 function 的返回类型可以是 object 或字符串(当存储中没有任何内容时)。
Also, savedValue
will never be falsy, so you will never return initialValue
.此外,
savedValue
永远不会是虚假的,所以你永远不会返回initialValue
。
Moreover, you call the hook with the params in the wrong order.此外,您以错误的顺序调用带有参数的钩子。
Here is a typed alternative:这是一个类型化的替代方案:
import React, { useState, useEffect } from "react";
function getSavedValue<T>(key: string, initialValue: T): T {
const stored = localStorage.getItem(key);
if (stored) {
return JSON.parse(stored) as T;
}
return initialValue;
}
export default function useLocalStorage<T>(key: string, initialValue: T) {
const [value, setValue] = useState<T>(() => getSavedValue(key, initialValue));
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [value]);
return [value, setValue] as const;
}
You can use it like this:你可以像这样使用它:
const [prevPet, setPrevPet] = useLocalStorage<Animal[]>("key", []);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.