在React中,值从其他组件更改后,useEffect不会更新

时间:2019-12-05 18:03:21

标签: javascript reactjs react-hooks use-effect

我正在尝试为自己做某种网上商店,但遇到了问题。 我想在NavBar组件(在每个页面中)中呈现购物车的尺寸。

我创建了一个购物车服务,在其中放置了所有添加的物品,它还具有addItemremoveItemgetCartgetCartSize的功能。

当我单击特定产品上的“添加/删除”时,我想NavBar上具有购物车大小的值将根据购物车大小而变化(来自getCartSize方法)。我已经尝试过使用useEffect挂钩,但是无法识别cartSize的值何时更改,我该怎么做?

这是我已经做的。

navbar.jsx

//...
//...
import {getTotalCount} from '../../services/myCart';

export default function Navbar() {
  // ...
  const [count, setCount] = useState();  

  useEffect(() => {
    setCount(getTotalCount());
    console.log('counto useeffect');
  },[getTotalCount()]);
  //},[getTotalCount]); doesn'work also.
  //},[count]); doesn'work also.

  return (
    <>
        <header className="navbar">
                <Link className="navbar__list-item__home-icon" to="/"><span><FaHome/></span></Link>
                <Link className="navbar__list-item" to="/products">Products</Link>            
                <h2>cart size--> {count}</h2>
                <Link className="navbar__list-item__cart-img" to="shopping-cart"><span><FaShoppingCart/></span></Link>   
        </header>
    </>
  );
}

myCart.js所有功能都可以正常使用,当我单击产品页面中组件上的“添加/删除”按钮时,我会调用它们。

var InTheCart = [

];
var totalCount = 0;

export function AddToCart(item) {
    // ... logic
    totalCount++;
}

export function ContainsInTheCart(id) {
    return InTheCart.findIndex(x=> x.item.id == id) != -1 ? true: false;   
}

export function RemoveFromCart(id) {
   // ... logic
        totalCount--;
}

export function getCart() {
    return InTheCart;
}

export function getTotalCount() {
    return totalCount;
}


2 个答案:

答案 0 :(得分:0)

反应之所以称为反应,是因为它在发生反应时会重新渲染。

要做到这一点,react组件需要以某种方式知道发生了什么变化。

在您显示的代码示例中,totalCount(由导出函数getTotalCount提供的全局访问)独立于react组件树,因此数据可以更改而无需react知道。

因此,问题是:如何使您的反应组件意识到这些变化?

存在一些机制,以下是其中一些:

  1. 使用像redux这样的全局状态管理器,通过redux动作和reducer来改变状态和组件中的useSelector,使他们知道任何更改,然后重新呈现

  2. 将保留购物车状态的反应上下文。该上下文既可以导出该数据,也可以导出将使数据突变的函数,因此可以在有权访问该上下文提供者的组件之间共享它们。

您的上下文可以通过以下方式在组件中使用:

  const cartContext = useContext(CartContext)
  const { cartState, addToCart, removeFromCart } = cartContext
  const { totalCount, inTheCart } = cartState

  [...somwhere later...]
  <ul><li onClick={() => removeFromCart(index)}>{inTheCart[index].name}</li></ul>
  <footer>{`${totalCount} items`}</footer>

我让您围绕现有功能构建上下文对象;)

答案 1 :(得分:0)

一个简单的解决方案是提升状态。在布局文件中创建状态,HeaderCart可以以count的身份访问Props。组件的useEffectstate发生变化时,将调用props