[英]How to effectively initialise client register callback in react functional component or hook
我正在尝试在反应功能组件中使用工厂类。 我需要基于组件道具进行初始化,并在第一次渲染或道具更改时进行。
这就是为什么我创建实例并将它的引用存储在 useEffect 中,该数组依赖于道具,以便在道具更改时始终获取新实例。
但是当我这样做时,需要一些特殊状态来强制组件更新。
我仍然认为有更好和更清洁的方法来做到这一点。 奇怪的是强制组件更新的虚拟状态。
所以我看起来正在运行的代码如下所示:
export const useClientLoader = (props: IClientLoaderProps) => {
const { backend, workspace, filter } = props;
const [,setInvalidate] = useState(0);
const [initStatus,setInitStatus] = useState<status>("pending");
const loaderRef = useRef<IClientLoader>();
const invalidate = ()=>{
// force component update via changing state
setInvalidate(i=>i+1);
}
useEffect(() => {
// init client instance
loaderRef.current = newClientHandler(backend, workspace, filter);
// update ref not update state and re-render component
// so i do force to update by dummy state update
invalidate();
}, [backend, workspace, filter]); // I need new instance when props changed
const onInitSuccess = () => {
setInitStatus("success");
};
// I need current pointer to client instance
const loader = loaderRef.current;
useEffect(() => {
if (loader) {
// subscribe callback
const onInitSuccessUnsubscribe = loader.onInitSuccess(onInitSuccess);
// init client and do magic on backend and wait for result via callback
loader.init();
return () => {
// Unsubscribe callback
onInitSuccessUnsubscribe();
};
}
}, [loader]); // I will do change just when I have new client instance
return {
initStatus:initStatus,
getUser: loader?.getUser
};
};
我想你可以只用一个 useEffect 来实现它,不需要分成两个然后被迫使用解决方法来触发重新渲染。 像这样:
const loaderRef = useRef<IClientLoader>();
const onInitSuccess = useCallback(() => {
setInitStatus("success");
}, []);
useEffect(() => {
loaderRef.current = newClientHandler(backend, workspace, filter);
const onInitSuccessUnsubscribe = loaderRef.current.onInitSuccess(onInitSuccess);
loaderRef.current.init();
return () => {
// Unsubscribe callback
onInitSuccessUnsubscribe();
};
}, [backend, workspace, filter, onInitSuccess]);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.