Change input props for withTracker from within a component

Maybe I am a bit dumb, but I am scratching my head about this:

I am implementing a chat like on WhatsApp, where the user will see the latest 20 messages when opening a chat and then would retrieve 20 more (earlier messages) when swiping the messages up to the top.

The React component should be self-containing, so it has its own UI that triggers the retrieval. However, since withTracker is a HOC, it only has access to the props that are fed in by the parent component. There is no way to access the current state of the component itself, where I would store my limit. It does not make any sense to me that the parent component itself would be involved in the whole process.

And since the chat may be used multiple times, using a global variable or a redux store entry wouldn’t make sense either.

What is the best practice to approach this?

I now found this thread:

Yet this ReactiveVar approach only works if there is only one such component on the page. Pretty much the same as if I used Redux for this. The only solution that comes to my mind so far is to setup another component between the parent component and the chat component that only holds the limit state. But that seems to be ugly to me, and it also causes headaches with forwardRefs.

Previously, we were holding the limits on a Session variable.

After running our chat app for more than a year, I revamped it recently. I no longer subscribe to the chat messages but instead subscribe to the chat room or conversation. This simplified everything and also lowered the load on our servers.

With this new structure, the room has an “update hash” that updates on changes in the room e.g. new messages posted. Updates on the hash are tracked and result in a method call that queries the new messages

With this new structure, we no longer track the limits but only the position of the starting message displayed. The method calls always retrieve a constant number of messages. And we no longer need to track data through Session (we are now just using state - we are using react)

3 Likes

Thanks for your response, interesting approach!

(Still looking for an approach if subscriptions are involved. For the time being, I implemented an intermediate component now, but that seems odd to me.)

There is a way which you can access the child component data from it’s parent: https://reactjs.org/docs/hooks-reference.html#useimperativehandle

1 Like

I’ve used this before, I would suggest going with the context API or something similar to Redux.
It’s cleaner and most developers know how it works, unlike useImperativeHandle

1 Like

I use Simpler-state

It’s absolutely fantastic. It can also use localstorage.

1 Like

Thanks for all your suggestions, highly appreciated. However, they do not seem to answer my original question: How I can trigger an update of a subscription (inside withTracker) from within the component itself and without using state management like Redux, which does not work well if the component might appear on one page multiple times.

Seems that is the limitation on this structure wherein you subscribe to the messages.

Either you keep the limit on a global variable (redux, session, etc.), or you have a parent component that triggers changes for the withTracker props.

1 Like

Yes, the parent component approach is the way I am doing it now. Redux or session variables would only work if you have one component (or you would have to maintain multiple instances somehow, which quickly gets ugly).

To maintain multiple versions using redux or session variable, you just need to make your keys variable pointing to specific component. Just require a unique name for the component and use the name as part of the keys