type State = {
filter: string;
pokemon: Array<string>;
setFilter: (filter: string) => void;
setPokemon: (pokemon: Array<string>) => void;
};
这种类型表示
pokemon
你商店的财产是一系列
String
(应该是小写
string
相反)。
pokemon.filter(({ name: { english } }) =>
此函数处理
宝可梦
数组作为一个对象
name
财产。这个
名称
它本身就是一个
object
拥有房产
english
这是一个
一串
.
这是两种不同且不兼容的类型,这就是为什么会出现错误。
你需要弄清楚哪个是正确的,哪个是错误的。链接
.txt
文件对此有所帮助。Pokemon对象看起来像这样:
{
id: 1,
name: {
english: "Bulbasaur",
japanese: "ãã·ã®ãã",
chinese: "å¦èç§å",
french: "Bulbizarre"
},
type: ["Grass", "Poison"],
base: {
HP: 45,
Attack: 49,
Defense: 49,
"Sp. Attack": 65,
"Sp. Defense": 65,
Speed: 45
}
};
所以我们可以看到
名称
property是一个具有属性的对象
英语
--
不
一
Array<string>
.
这取决于你想对自己的类型有多具体。你可以描述一下
名称
财产作为
type Name = Record<string, string>
该对象的键和值都是
一串
这意味着任何
一串
可以用作密钥。所以你可能想更具体地说,这是一个看起来像这样的对象:
type Name = {
english: string;
japanese: string;
chinese: string;
french: string;
}
如果你试图访问无效的密钥,这会给你一个错误,比如
name.spanish
.
这个
宝可梦
您的财产
State
是一个
Array
但它不是一个数组
一串
--这是一系列口袋妖怪物品。我们需要定义a的类型
Pokemon
基于您的数据文件。
type Pokemon = {
id: number;
name: {
english: string;
japanese: string;
chinese: string;
french: string;
};
type: Array<string>;
base: {
HP: number;
Attack: number;
Defense: number;
"Sp. Attack": number;
"Sp. Defense": number;
Speed: number;
}
}
你的
国家
类型可以使用此
宝可梦
类型:
type State = {
filter: string;
pokemon: Array<Pokemon>;
setFilter: (filter: string) => void;
setPokemon: (pokemon: Array<Pokemon>) => void;
};
由于您使用的是泛型
<State>
在你的
create
函数中,您可以通过删除参数上的类型来修复弹出的错误。它们将从您的
国家
类型。
const useStore = create<State>((set) => ({
// set initial values here
filter: "",
pokemon: [],
setFilter: (filter) =>
set((state) => ({
...state,
filter,
})),
setPokemon: (pokemon) =>
set((state) => ({
...state,
pokemon,
})),
}));
在您的第一个版本中
PokemonTable
没有拿任何道具。这个更接近正确。因此,您可以删除您的
PkTableProps
界面。你需要的所有数据都来自商店,而不是道具。
现在
国家
有正确的类型,你的首字母
口袋妖怪桌
组件工作!
const PokemonTable = () => {
const pokemon = useStore((state) => state.pokemon);
const filter = useStore((state) => state.filter);
return (
<table width="100%">
<tbody>
{pokemon
.filter(({ name: { english } }) =>
english.toLowerCase().includes(filter.toLowerCase())
)
.map(({ id, name: { english }, type }) => (
<tr key={id}>
<td>{english}</td>
<td>{type.join(", ")}</td>
</tr>
))}
</tbody>
</table>
);
};
嵌套破坏
.filter(({ name: { english } })
可能很难阅读。如果你这样写,可能会更容易理解。
const PokemonTable = () => {
const pokemonArray = useStore((state) => state.pokemon);
const filter = useStore((state) => state.filter);
return (
<table width="100%">
<tbody>
{pokemonArray
.filter(pokemon =>
pokemon.name.english.toLowerCase().includes(filter.toLowerCase())
)
.map((pokemon) => (
<tr key={pokemon.id}>
<td>{pokemon.name.english}</td>
<td>{pokemon.type.join(", ")}</td>
</tr>
))}
</tbody>
</table>
);
};
最后一件事——你只需要
useEffect
它获取口袋妖怪数据并运行一次。你可以给它一个空的依赖数组
[]
或一个依赖数组
[setPokemon]
.
Working CodeSandbox Link