0

如果我的组件没有 HOC,它确实会触发,但现在我将组件包裹在 withSpinner Hoc 内部,但它不会触发获取开始。

const CollectionPage = (props) => {
  const { isCollectionLoaded, isCollectionFetching } = props;

  useEffect(() => {
    props.fetchCollectionsStart();
  }, []);
  const { title, items } = props.collection;

  return (
    <div className="collection-page">
      <SearchBar />
      <h2 className="title">{title} </h2>

      <div className="items">
        {items.map((item) => (
          <CollectionItem key={item.id} {...props} item={item} />
        ))}
      </div>
    </div>
  );
};

const mapStateToProps = (state, ownProps) => ({
  collection: selectCollection(ownProps.match.params.collectionId)(state),
  isCollectionFetching: selectIsCollectionFetching(state),
  isCollectionLoaded: selectIsCollectionsLoaded(state),
});

export default WithSpinner(
  connect(mapStateToProps, { fetchCollectionsStart })(CollectionPage)
);

这是状态的控制台。

在此处输入图像描述

这是 withSpinner Hoc:

const WithSpinner = (WrappedComponent) => ({
  isCollectionLoaded,
  ...otherProps
}) => {
  return !isCollectionLoaded ? (
    <SpinnerOverlay>
      <SpinnerContainer />
    </SpinnerOverlay>
  ) : (
    <WrappedComponent {...otherProps} />
  );
};

export default WithSpinner;

正如您从图像中看到的那样,我只看到微调器正在旋转,因为 fetchCollectionStart 没有触发,所以 redux 存储没有更新。

4

2 回答 2

0

isCollectionLoadedfetchCollectionsStart一旦调度完成并且 redux 状态更新,这将是真的(我怀疑) 。

但是你有一个问题,fetchCollectionsStart只在 mount 阶段调度,因为默认情况下是 false 并且blocks CollectionPage,所以永远不会发生。isCollectionLoadedWithSpinnerCollectionPage

我建议将调度 useEffect 移动到 Spinner Hoc,考虑到您的代码结构,这很有意义。您的 hoc 可能类似于:

const WithSpinner = (WrappedComponent) => ({
  isCollectionLoaded,
  fetchCollectionsStart,
  ...otherProps
}) => {

    useEffect(() => {
    fetchCollectionsStart();
  }, []);

  return !isCollectionLoaded ? (
    <SpinnerOverlay>
      <SpinnerContainer />
    </SpinnerOverlay>
  ) : (
    <WrappedComponent {...otherProps} />
  );
};

export default WithSpinner
于 2020-06-19T00:55:46.700 回答
0

这是因为您的属性isCollectionLoaded没有被更新,并且您将微调器更新为 WrappedComponent 的视图取决于isCollectionLoaded正在更改的属性。

您已经在使用带有 redux 的高阶组件connect,但是您尝试做的是使用 Spinner 和集合搜索器创建一个复合组件。withSpinner在第二个示例中的实例将需要公开或调用该connect函数,以便 redux 可以发挥它的魔力。

通过在第一个示例中公开命名组件,您将公开一个具有绑定逻辑的 React 组件:

export default WithSpinner(
  connect(mapStateToProps, { fetchCollectionsStart })(CollectionPage)
);

这可以用作:

<WithSpinner/>

与创建复合组件相比,更简单的解决方案是将微调器添加到CollectionPage组件中:

 if (!isContentLoaded) {
   return (<Spinner/>);
 }
 return (
    <div className="collection-page">
      <SearchBar />
      <h2 className="title">{title} </h2>

      <div className="items">
        {items.map((item) => (
          <CollectionItem key={item.id} {...props} item={item} />
        ))}
      </div>
    </div>
  );
于 2020-06-19T00:56:04.403 回答