我正在尝试在打字稿中编写 HOC 以在用户必须等待时呈现微调器。
我从这篇文章开始。
这是WithFullScreenSpinnerHOC.ts
我的打字稿代码:
import RX = require('reactxp');
const styles = {
semiTransparentBlackBbackground: RX.Styles.createViewStyle(
{ backgroundColor: 'rgba(0, 0, 0, 0.7)', justifyContent: 'center' }
),
};
export interface withFullScreenSpinnerProps {
};
export interface withFullScreenSpinnerState {
showSpinner: boolean
};
// Higher-Order component that will allow any component to display a fullscreen activity indicator
const withFullScreenSpinner = <P extends withFullScreenSpinnerProps, S extends withFullScreenSpinnerState>(
WrappedComponent: new (props: P) => RX.Component<P, S>
) =>
class WithFullScreenSpinner extends RX.Component<P & withFullScreenSpinnerProps, S & withFullScreenSpinnerState> {
constructor(props) {
super(props);
this.state = {
showSpinner: false
} as S & withFullScreenSpinnerState;
}
render() {
return (
<RX.View style={{ flex: 1 }}>
<WrappedComponent {...this.props}>
</WrappedComponent>
{this.state.showSpinner &&
<RX.View
style={styles.semiTransparentBlackBbackground}
>
<RX.ActivityIndicator
size="large"
color="black"
/>
</RX.View>}
</RX.View>
);
}
};
export default withFullScreenSpinner;
将使用此 HOC 的组件必须具有 showSpinner 状态变量。
所以我有一个登录页面,例如用这个 HOC 包装。
import WithFullScreenSpinner from './WithFullScreenSpinnerHOC'
// The state of the sign-in component (data entered by the user)
interface signInState {
username: string,
password: string,
errorMessage?: string
ready: boolean,
session: any,
showSpinner: boolean
};
class SignIn extends RX.Component<signInProps, signInState> {
constructor(props) {
super(props);
this.state = {
username: '',
password: '',
errorMessage: null,
ready: false,
session: null,
showSpinner: false
};
}
private showSpinner() {
this.setState((prevState, props) => {
let newState = { ...prevState };
newState.showSpinner = true;
return newState;
})
}
private hidepinner() {
this.setState((prevState, props) => {
let newState = { ...prevState };
newState.showSpinner = false;
return newState;
})
}
// Do the Sign In using the auth API that comes through the props of the WithAuth HOC
doSignIn = async (username: string, password: string) => {
const { authLayer } = this.props;
try {
this.showSpinner();
const user = await authLayer.signIn(username, password);
const requireMFA = (user.Session !== null);
this.setState((prevState, props) => {
let newState = { ...prevState };
newState.showMFAPrompt = requireMFA;
newState.session = user.session;
return newState;
});
// Should be null if MFA enabled
return user.signInUserSession;
}
catch (err) {
console.log(err);
this.setState((prevState, props) => {
let newState = { ...prevState };
newState.errorMessage = err.message;
return newState;
});
}
finally {
this.hidepinner();
}
}
render() {
return (
);
}
};
export default WithFullScreenSpinner(SignIn);
但是我在这里遗漏了一些东西,因为更改包装组件中的状态不会触发 HOC 渲染方法。
我在 HOC 的 render 方法中设置了一个断点,以确认它只被调用一次。
任何帮助表示赞赏。
编辑1:这是设计使然,组件不相关,因此我需要一种相互通信的方式。如果可行,我将尝试Resub并回答我自己的问题。
编辑 2:我在下面发布了我的解决方案。我还没有接受它作为正确答案,因为我想提出建议/意见。