我正在用react
、redux-toolkit
和typescript
做一个库项目(更多说明请参见链接)。
我在做一个addToWishlist
函数:用户只需点击星星,代码就会调度修补数据库的操作,状态也随之更新。2还有一个操作可以将图书从列表中删除。
在<Wishlist />
组件中,我当然要呈现每本书的标题和其他数据。因此我使用useAppSelector
来检索wishlist
和整个list
的书,并在filter
和map
的帮助下,我将得到相应的书,但我无法呈现它们,因为它给了我一个ts
错误:index.d.ts(1373, 9): The expected type comes from property 'children' which is declared here on type 'DetailedHTMLProps<HTMLAttributes<HTMLUListElement>, HTMLUListElement>'
个
- 关于结构的重要说明 *
wishlist
是一个字符串数组,这些字符串是books的id。而books的整个list
是一个对象数组:每个对象是一本书,具有标题、作者、ID等。
我的问题:
1.这到底是怎么回事?
1.基本上,是在wishlist
数组中保存id(像我所做的那样)更好,这样我就必须用filter
和map
在我的<Wishlist />
组件中检索图书的数据,还是保存整本书(或者至少是我需要的信息)更好,这样更容易获得数据?
1.在第一种情况下,当我必须使用filter
和map
检索数据时,呈现列表的最佳实践是什么?
以下是尝试:
const Wishlist = () => {
const dispatch = useAppDispatch();
const wishlist = useAppSelector(state => state.user.userInfo.wishlist);
const list = useAppSelector(state => state.catalogue.list);
const renderBooks = () => {
return wishlist.map(wishId => {
list.filter(book => {
if (book.id === wishId) {
return (
<li>{book.title}</li>
)
}
})
})
}
return (
<ul>
{renderBooks()}
</ul>
)
};
export default Wishlist;
已编辑-可能问题不在于方法的连接,而在于函数调用中的某些内容?
- 另一个更小的例子,另一个解决方案,但同样的问题 *
interface fakeObj {
id: string;
name: string;
}
const fakeIds = ['5', '12', '878'] // this is my 'wishlist', containing only ids
const fakeList: fakeObj[] = [ // this is my 'list', containing objects, which were single books
{ id: '334', name: 'Tony' },
{ id: '5', name: 'Milly' },
{ id: '12', name: 'Jack' },
{ id: '7', name: 'Stew' },
{ id: '878', name: 'Mark' },
{ id: '87998', name: 'Greg' }
]
const renderArray = () => {
const arr: fakeObj[] = [];
fakeIds.forEach(id => {
fakeList.filter(obj => {
if (obj.id === id) {
arr.push(obj)
}
})
})
return arr; // the returned array is what I want: an array continaing the objects that i need
}
return (
<ul>
{/* The problem actually is here! */}
{renderArray()}
</ul>
)
1条答案
按热度按时间30byixjq1#
您没有正确使用**.filter()或.map()**,这是导致错误的原因。
您拒绝的上述注解是此问题的正确解决方案。
添加的已编辑示例甚至更令人困惑,因为您不再尝试返回可渲染元素,因为返回的是一个对象数组,无法在UL中渲染。
所以,我要回到最初的例子。
问题1:
您正尝试在传递给**.filter的回调中返回JSX元素().这不是怎么.filter()工作。您应该将回调传递给.filter()根据您是要筛选出还是要筛选出元素,返回TRUE或FALSE。例如,
listOfCounts.filter( count => count > 5);
将返回listOfCounts**中所有元素的修改数组大于5。问题2:
您当前正在调用**.map()首先调用**,这是错误的,然后还调用**.filter()在.Map内()而不是在过滤器之后链接Map。因为现在,您.map()调用甚至没有尝试返回表示要呈现的书名的JSX元素列表。这些调用的链接方式与你的方式相反。下面是一个非常简单的使用.map()**的例子:
将**.map()与.filter()**结合使用的简单示例:
它会过滤掉所有不以大写J开头的名字。
上面的解决方案,先生. Rafique提供给你是正确的/非常接近正确的,这取决于确切的实现,所以我建议你合并这个添加的信息与他的解决方案.