繁体   English   中英

如何在反应 redux 中混合全局和本地 state

[英]How to mix global and local state in react redux

我有一个产品页面,它maps了所有产品,foreach 它显示产品图像和一个“添加到购物车”按钮。

单击添加到购物车时,我从我的 redux 操作中调用了 function。 该 function 向后端发送 API 请求。 在通话进行时,我想用装载机替换添加到购物车按钮。

在我的 redux 购物车 state 中,有一个 boolean 属性cartLoading在呼叫开始时设置为 true,呼叫解决后设置为 false。 这就是问题所在:如果在我的EachProduct组件中,我将天气逻辑或不显示加载程序绑定到购物车 state 中的cartLoading的值,那么发生的事情是页面上的所有“添加到购物车”按钮都替换为装载机,因为cartLoading是全局 state 属性。 但是我也无法使用 useState 加载本地useState因为我无法知道组件的 scope 天气对后端的调用已经完成,因为它是由全局操作 ZC1C425268E68385D1AB5074C1 完成的。

我尝试subscribe store并在单击按钮时cartLoading的更改,但由于我不知道通话结束时组件 scope 中的内容,所以我不知道何时取消订阅。 所以发生的事情是当我在第一个项目上单击“添加到购物车”时,它工作正常,只有那个项目显示了一个加载器。 但是当我点击另一个项目时,第一个和第二个都显示加载程序,因为第一个和第二个现在订阅了全局cartLoading state 而第一个从未取消订阅。

我也尝试了以下代码,但是没有显示加载器:

const [loading, setLoading] = useState(false);

  const [unsubscribe, setUnsubscribe] = useState(null);

  const onSubmit = (e, variantToken) => {
    e.preventDefault();

    const subscribeToCartLoadingState = () => {
      let loading = store.getState().cart.cartLoading;
      setLoading(loading);
    };

    setUnsubscribe(store.subscribe(subscribeToCartLoadingState));

    addProductToCart(
      {
        prodToken: variantToken,
        cartProdQuantity: 1,
      },
      cartToken
    );
  };

  useEffect(() => {
    console.log(unsubscribe);

    if (!cartLoading && unsubscribe) unsubscribe();
  }, [cartLoading]);

然后是我的 jsx 中的按钮:

!loading ? (
           { <button
              type="button"
              onClick={(e) => onSubmit(e, product.variants[0].variantToken)}
              className="btn waves-effect blue"
            >
              Add to cart
            </button>
          ) : (
            <MiniSpinner />
          )}

对此有任何解决方法吗? 是否只能选择在本地发出后端请求?

Ps 如果你对这个问题有更好的标题,请随时编辑。

正如我在评论中提到的,我认为如果您重构您的 redux state 以指定具体加载哪些项目,那么您将拥有最好的运气。 那么您就不必担心协调全局和本地 state。

如果您打算使用当前的 state 设置,我认为以下可能在没有您创建的subscribe功能的情况下工作。 基本上,您可以在调度操作时将本地loading state 设置为true 由于您已从cartLoading映射到 cartLoading,因此您只需要在更改时运行的效果并将本地loading state 翻转回false

const [loading, setLoading] = useState(false);

const onSubmit = (e, variantToken) => {
  e.preventDefault();
  setLoading(true);
  addProductToCart(
    {
      prodToken: variantToken,
      cartProdQuantity: 1,
    },
    cartToken
  );
};

useEffect(() => {
  if (!cartLoading && loading) setLoading(false);
}, [cartLoading]);

也许你可以使用:

https://github.com/RisingStack/react-easy-state

或者

https://github.com/ctrlplusb/easy-peasy

他们可以管理全球和本地商店。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM