Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typical usage pattern not clear #42

Open
quain24 opened this issue Oct 21, 2024 · 3 comments
Open

Typical usage pattern not clear #42

quain24 opened this issue Oct 21, 2024 · 3 comments

Comments

@quain24
Copy link

quain24 commented Oct 21, 2024

Hi!

I really like your work, but I'm having trouble understanding the typical usage pattern - specifically "how should this work?" based on the README and examples.

Typically, I expect a custom context provider to work something like this (based on your library, in pseudo-code):

const SignalRContext = createSignalRContext();

export const MainComponent = () => {
    return (
        <SignalRContext.Provider
            url={'https://localhost:5000/hub'}
            onOpen={con => console.log('Connection Id: ' + con.connectionId)}
            onReconnect={con => console.log('Reconnected Id: ' + con.connectionId)}
        >
            <ACustomComponent>
                <NestedComponent />
            </ACustomComponent>
        </SignalRContext.Provider>
    );
};

My assumption is that I should create a single provider for a large portion of my project, maintaining one connection throughout the user session. This would allow all components that need server communication to use your hooks/methods. In my case, SignalR will be used for:

  1. Global updates (connection dropped, user logged out, etc.) shown as popups independent of the current screen
  2. Updates for specific components (e.g., "text changed in a text field")

Then, inside ACustomComponent and/or NestedComponent (separate files for each component), I should be able to access the context's methods, specifically invoke and useSignalREffect.

However, from what I observe (and I may be wrong since I'm not deeply experienced with React), to access these functionalities, I have to create a new SignalRContext inside the aforementioned components. This causes the connection to be null, and the functionality doesn't work.

I've tried working around this by replacing:

const SignalRContext = createSignalRContext();

with:

export const SignalRContext = createSignalRContext();

and using this export to access invoke and useSignalREffect.
However, this seems incorrect as it contradicts the typical React context pattern usage which should allow me to just import "context" functionalities from your implementation and use them directly.

Am I doing/understanding something wrong way, does your implementation need adjustment or maybe there is no way around it?

@hosseinmd
Copy link
Owner

Hi,
createSignalRContext is designed for creating few signalr connection in and app.
Let me explain by an example, assume you need tow connection and use them together in a component, so you just need use hook of each connection. this approach is because of it.

@quain24
Copy link
Author

quain24 commented Oct 22, 2024

So, in theory, according to react guides about hooks - i should be able to encompass my components in nested providers, like:

const SignalRContext = createSignalRContext();
const SignalRSecondContext = createSignalRContext();
export const MainComponent = () => {
    return (
        <SignalRContext.Provider
            url={'https://localhost:5000/hub'}
            onOpen={con => console.log('Connection Id: ' + con.connectionId)}
            onReconnect={con => console.log('Reconnected Id: ' + con.connectionId)}
        >
            <SignalRSecondContext.Provider
            url={'https://localhost:10000/hub2'}
            >
                <ACustomComponent>
                    <NestedComponent />
                </ACustomComponent>
            </SignalRSecondContext.Provider>
        </SignalRContext.Provider>
    );
};

And be able to resolve the hook inside nested component for each one separately, yes?

Possibly using some sort of a key, given that the constructor for provider would require said key, like createSignalRContext('con1')?
This would require invoke and useSignalREffect to also require said identifier as mandatory parameter, as well as use of context hook inside of your wrapper for storing all of the created connections plus logic to handle unmount.

Is this something that you could consider in the future or should I stay with my current approach stick with export const SignalRContext = createSignalRContext(); for each provider created?

This seems a bit dangerous, in theory you could import this anywhere, not just inside components encompassed by your provider(?).

Also, thank you for such a quick reply!

@hosseinmd
Copy link
Owner

hosseinmd commented Oct 23, 2024

This seems a bit dangerous, in theory you could import this anywhere, not just inside components encompassed by your provider(?).

This issue is about react Context Provider, I don't think we should be wary about it.

Is this something that you could consider in the future or should I stay with my current approach stick with export const SignalRContext = createSignalRContext(); for each provider created?

I have no resistance to change, but I don't see any reason to change it now. Stay with it, i will fix any issue if you encounter it.

Possibly using some sort of a key, given that the constructor for provider would require said key, like createSignalRContext('con1')?

Creating an instance makes it easier to manage stuffs related to that instance. For example, we could make a different provider with specific parameters.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants