【问题标题】:useSelector in child component re-rendering parent component子组件中的useSelector重新渲染父组件
【发布时间】:2020-07-13 16:40:19
【问题描述】:

我是新手,我开始使用 redux,但我注意到每次我的子组件(图标包)更改包中的项目数时,整个标题组件重新呈现。我试过了,

  • 使用备忘录
  • 创建选择器
  • React.memo(标题)

有什么建议吗?

标题组件

const Header = ({ currentUser }) => {
    const { hidden } = useSelector(state => state.cart);

    return (
        <div className="header">
            ...
            <div className="options">
                ...
                <CartIcon />
            </div>

        </div>);
};

export default Header;

购物车图标组件

const CartIcon = () => {
    const selectCartItems = createSelector(
        state => state.cart,
        cart => cart.cartItems
    );
    const cartItems = useSelector(selectCartItems);
    const dispatch = useDispatch();

    const totalItemsCount = (cartItems) => {
        return cartItems.reduce((acc, crr) =>
            acc + crr.quantity
            , 0)
    };
    const totalItems = useMemo(() => totalItemsCount(cartItems), [cartItems])

    return (
        <div className="cart-icon" onClick={(() => dispatch(actionCreators.onToggleCart()))}>
            <ShoppingIcon className="shopping-icon" />
            <span className="item-count">{totalItems}</span>
        </div>
    );
};

export default CartIcon;

【问题讨论】:

    标签: reactjs redux react-redux


    【解决方案1】:

    这可能是因为您的 state.cart 值正在使用购物车中的商品进行更新。 useSelector 会在返回的引用更改时强制重新渲染,因此 Header 会在任何购物车数据更改时重新渲染。

    您应该将其更改为仅选择Header 组件需要的数据:

    const hidden = useSelector(state => state.cart.hidden);
    

    【讨论】:

    • 解决了这个问题!谢谢马克!我假设然后不需要 useMemo() 但 createSelector() 应该按我的方式保留?
    • 我想知道为什么有人会否决解决 OP 问题的答案,我 +1。我正要编辑我的答案,但是....
    • useMemo 可以按原样使用,尽管每次重新渲染组件时重新计算这样的值并没有什么问题。
    【解决方案2】:

    在Header中,如果hidden改变值,组件会重新渲染。

    dispatch(actionCreators.onToggleCart()) 更新 state.cart 了吗?

    您应该在标头中取消订阅 hidden 以测试这是否会导致重新渲染。

    【讨论】:

      猜你喜欢
      • 2018-08-12
      • 2019-06-01
      • 2020-02-13
      • 2021-12-01
      • 1970-01-01
      • 2019-02-26
      • 2016-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多