我创建了以下高阶组件:
const baseComponent = (WrappedComponent: React.ComponentClass<any>) => (props: IKeyValue) => {
if (props.isLoading) {
return (
<LoadingSpinnerComponent shown={true} />
);
}
return (
<WrappedComponent {...props} />
);
};
这导致无限期地调用此组件。
(componentDidMount
中的myComponent
表示正在重新创建此组件。
我以下列方式使用它:
export default connect(
mapStateToProps,
dispatchToProps,
)(baseComponent(myComponent)) as React.ComponentClass<any>;
删除if部分时:
if (props.isLoading) {
return (
<LoadingSpinnerComponent shown={true} />
);
}
该组件只会被调用一次。 我试图深入调试反应lib代码,但魔术对我来说是一个奇迹。有什么想法吗?
提前致谢!
编辑:
完整代码:
myComponent
:
class MiniCatalogContainer extends React.PureComponent<IProps, void> {
public componentDidMount() {
const { fetchCatalog} = this.props;
fetchCatalog({path});
}
public render() {
...
}
}
export default connect(
mapStateToProps,
dispatchToProps,
)(baseComponent(MyComponent)) as React.ComponentClass<any>;
promise-middleware
import { Dispatch } from 'react-portal/src/interfaces';
import isPromise from 'react-portal/src/utils/is-promise';
interface IOptions {
dispatch: Dispatch;
}
export default function promiseMiddleware({ dispatch }: IOptions) {
return (next: Dispatch) => (action: any) => {
if (!isPromise(action.payload)) {
return next(action);
}
const { types, payload, meta } = action;
const { promise, data } = payload;
const [ PENDING, FULFILLED, REJECTED ] = types;
/**
* Dispatch the pending action
*/
dispatch( { type: PENDING,
...(data ? { payload: data } : {}),
...(meta ? { meta } : {}),
});
/**
* If successful, dispatch the fulfilled action, otherwise dispatch
* rejected action.
*/
return promise.then(
(result: any) => {
dispatch({
meta,
payload: result,
type: FULFILLED,
});
},
(error: any) => {
dispatch({
meta,
payload: error,
type: REJECTED,
});
},
);
};
}
解决方案:
正如@Shleng注意到的那样,循环是因为我在组件内部进行了fetch
调用。我最终得到了简单的解决方案:
const baseComponent = (WrappedComponent: React.ComponentClass<any>) => (props: IKeyValue) => {
if (props.isLoading) {
return (
<LoadingSpinnerComponent shown={true} />
<WrappedComponent {...props} />
);
}
return (
<WrappedComponent {...props} />
);
};
答案 0 :(得分:2)
因为您在包裹的组件fetchCatalog
内调用了componentDidMount
,所以工作流会产生如下所示的循环:
mount WrappedComponent -> fetch -> mount Spinner -> loaded -> mount WrappedComponent -> fetch (loop!)
isLoading: false -> true -> false -> true