Skip to content

Instantly share code, notes, and snippets.

@otakustay
Last active February 4, 2021 09:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save otakustay/e3d4149284d03e89d27dc49d5c48774a to your computer and use it in GitHub Desktop.
Save otakustay/e3d4149284d03e89d27dc49d5c48774a to your computer and use it in GitHub Desktop.
Convert HOC to Hook
// HOC版本
const withDelayHint = (loadingPropName, delay) => ComponentIn => class extends Component {
state = {
timer: null,
isDelayed: false
};
tryStartTimer = () => {
clearTimeout(this.state.timer);
this.setState({isDelayed: false});
if (this.props[loadingPropName]) {
const timer = setTimeout(
() => this.setState({isDelayed: true}),
delay
);
this.setState({timer))});
}
}
componentDidMount() {
this.tryStartTimer();
}
compoenntWillUnmount() {
clearTimeout(this.state.timer);
}
componentDidUpdate(prevProps) {
if (this.props[loadingPropName] !== prevProps[loadingPropName]) {
this.tryStartTimer();
}
}
render() {
const {isDelayed} = this.state;
return <ComponentIn {...this.props} isDelayed={isDelayed} />;
}
}
// 翻译成Hook版本
const useDelayHint = (loading, delay) => {
const timer = useRef(null); // 不影响渲染的state变成useRef
const [delayed, setDelayed] = useState(false); // setState变成useState
// 生命周期变成useEffect
useEffect(
() => {
clearTimeout(timer.current);
if (!loading) {
timer.current = setTimeout(
() => setDelayed(true),
delay
);
}
return () => clearTimeout(timer.current); // willUnmount
},
[loading] // didUpdate里的if的条件放在这里
);
return delayed;
};
// 使用方法
const MyComponent = ({isLoading, data}) => {
const delayed = useDelayHint(isLoading, 2000);
if (delayed) {
return '再等等';
}
if (isLoading) {
return '加载中';
}
return (
<div>
{data}
</div>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment