useEffect不在Hoc内部触发

时间:2020-06-18 23:40:18

标签: javascript reactjs react-hooks high-order-component

如果我的组件没有HOC,它将触发,但是现在我将组件包裹在Spinner 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)
);

这是状态的控制台。

enter image description here

这是withSpinner Hoc:

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

export default WithSpinner;

从图像中可以看到,我只是看到微调器在旋转,因为fetchCollectionStart没有触发,所以redux存储没有更新。

2 个答案:

答案 0 :(得分:0)

isCollectionLoaded将为真(我怀疑),一旦调度fetchCollectionsStart完成并且redux状态已更新。

但是您有一个问题,fetchCollectionsStart仅在CollectionPage的安装阶段分派,因为isCollectionLoaded默认为false并且WithSpinner阻止CollectionPage

我建议将调度useEffect移至Spinner Hoc,这对于您的代码结构是有意义的。您的临时文件夹可能类似于:

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

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

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

export default WithSpinner

答案 1 :(得分:0)

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

您已经将higher-order component与redux的connect一起使用,但是您要尝试的是使用Spinner和collection搜索器创建一个composite component。在第二个示例中,您的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>
  );