Skip to main content

Use scopeBind in Next.js

There are situations when we need to get values from external libraries through callbacks. If we directly bind events, then we will face the loss of the scope. To solve this problem, we can use scopeBind.

We have some external library that returns us the status of our connection. Let's call it an instance in the store and call it $service, and we will take the status through an event.

import { createEvent, createStore } from 'effector';

const $connectStatus = createStore('close');
const connectEv = createEvent();

sample({
clock: connectEv,
targt: $connectStatus,
})

To pick up the current scope, let's write a callback in _app.tsx under our clientScope:

...

let clientScope: Scope;

export const getCurrentScope = () => clientScope;

...

Now we need to save the current scope somewhere.

import { createEvent, createStore, sample, Scope } from 'effector';

const getCurrentScopeEv = createEvent<Scope>();
const $currentScope = createStore<Scope | null>(null);

sample({
clock: getCurrentScopeEv,
target: $currentScope,
});

And on our page we take our scope:

import { useEvent } from 'effector-react/scope';

...

const getScope = useEvent(getCurrentScopeEv);

useEffect(() => {
const scope = getCurrentScope();

getScope(scope);
}, [getScope]);

...

Next, we need to create an effect, within which we will connect our event and service.

import { attach, scopeBind } from 'effector';

const connectFx = attach({
source: {
service: $service,
currentScope: $currentScope,
},
async effect({ service, currentScope }) {
return await service.on('service_start', scopeBind(connectEv), { scope: currentScope });
},
});

After calling our effect, the event will be tied to the scope and will be able to take the current value from our service.