如何避免多次使用useSelector钩子?



我在解耦业务逻辑和ui时遇到了麻烦。我是新手。我知道我的组件包含了太多的责任。另外,我不确定是否使用useSelector钩子的很多变量是一个好主意,但我不知道如何避免它。请有人解释一下如何修复它或给一些建议,应该读/看什么?

const Catalog = () => {
const dispatch = useDispatch();
const items = useSelector(state => state.catalog.plantsList);
const isFetching = useSelector(state => state.catalog.isFetching);
const currentPage = useSelector(state => state.catalog.currentPage);
const totalCount = useSelector(state => state.catalog.totalCount);
const limitItems = useSelector(state => state.catalog.limitItems);
const pagesCount = Math.ceil(totalCount/limitItems);
const pages = [];
createPages(pages, pagesCount, currentPage);
useEffect(() => {
dispatch(fetchData(currentPage, limitItems));
}, [currentPage]);
let plantItems = items.map(p => <PlantItem key={p.id} id={p.id} image={p.image} name={p.name}
cost={p.cost}/>)
return (
<div className={s.catalog}>
<p className={s.catalog__description}>Сдавая пластик в пункты приема, Вы получаете природные баллы. За один
килограмм пластика можно получить
10 природных баллов.</p>
<div className={ isFetching === false ? s.catalog__list : s.fetching }>
{
isFetching === false ?
plantItems
:
<Preloader/>
}
</div>
<div className={s.catalog__pages}>
{pages.map((page, index) => <div
key={index}
className={currentPage == page ? s.currentPage : s.page}
onClick={() => dispatch(setCurrentPage(page))}>{page}</div>)}
</div>
</div>
);
};

你绝对不应该做这里的其他答案所建议的:useSelector(state => state.catalog)将在state.catalog.anythingUnrelated更新时更新你的组件,即使你只需要state.catalog.a,state.catalog.bstate.catalog.c在你的组件。你会过度订阅,你的应用程序会被过度渲染。

总是有选择地订阅你实际需要的数据。多次调用useSelector完全没问题,而且通常比过度订阅性能更好。(我们甚至建议在样式指南中这样做)

作为一种替代方法,您还可以将重要数据的计算从组件移到选择器中,并创建一个记忆选择器。这不会减少很多代码,但会将其移出组件。

或者您将非记忆选择器与自定义比较函数结合使用,如:

const {
plantsList: items,
isFetching,
currentPage,
totalCount,
limitItems
} = useSelector(({catalog}) => ({
plantsList: catalog.plantsList,
isFetching: catalog.isFetching,
currentPage: catalog.currentPage,
totalCount: catalog.totalCount,
limitItems: catalog.limitItems
}), shallowEqual);

但是正如你所看到的,代码也没有少很多

最后:有多个useSelector调用是很好的。

看看你的例子,你可以使用反结构属性。像这样:

const {
plantsList: items,
isFetching,
currentPage,
totalCount,
limitItems
} = useSelector(state => state.catalog);

最新更新