React with Inversify使useEffect无限循环



我使用CRA+TS,并集成了一个用于依赖项注入的自定义挂钩(Inversify(。这是我的代码:

// DI Provider
export const InversifyContext = React.createContext<{ container: Container | null }>({ container: null });
export const DiProvider: React.FC<Props> = (props) => {
return <InversifyContext.Provider value={{ container: props.container }}>{props.children}</InversifyContext.Provider>;
};

// Custom Hook
export function useInjection<T>(identifier: interfaces.ServiceIdentifier<T>): T {
const { container } = useContext(InversifyContext);
if (!container) {
throw new Error();
}
console.log("This is hook"); // This gets printed infinitely
return container.get<T>(identifier);
}
// Injectable Service
@injectable()
class MyService{
// some methods
}
// index.tsx
const container = new Container();
container.bind<MyService>("myService").to(MyService);
ReactDOM.render(
<DiProvider container={container}>
<MyComponent />,
document.getElementById("root")
);
// MyComponent.tsx
const MyComponent: React.FC = () => {
const myService = useInjection<MyService>("myService");
useEffect(() => {
myService.getData(); // Loop call
}, [myService]);
}

现在,当我调试代码时,我看到提供程序被无限地呈现,这导致了组件的重新呈现。

首先,您需要了解为什么会发生这种情况。

当您在useEffect钩子中使用注入的服务作为依赖项(您应该这样做(时,它会触发一个组件重新调用程序,该程序将调用useInjection钩子,并返回一个新的/更新的MyService实例,因为该实例已更改,useEffect将再次被触发,这将导致递归调用。

我同意您不应该忽略useEffect依赖项。这里的一个简单解决方案是将服务存储在钩子中。

所以你的记忆挂钩将变成:

export function useInjection<T>(identifier: interfaces.ServiceIdentifier<T>): T {
const { container } = useContext(InversifyContext);
if (!container) {
throw new Error();
}
console.log("This is hook"); // This gets printed infinitely
return useMemo(() => container.get<T>(identifier), [container, identifier]);
}

您的钩子现在将返回服务实例的记忆版本。

相关内容

  • 没有找到相关文章

最新更新