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

How can I reflect membership state updates? #3029

Open
Liamandrew opened this issue Mar 18, 2025 · 2 comments
Open

How can I reflect membership state updates? #3029

Liamandrew opened this issue Mar 18, 2025 · 2 comments

Comments

@Liamandrew
Copy link

Liamandrew commented Mar 18, 2025

Hi,

I have a scenario where users can view channels they aren't a member of.

When viewing a channel they aren't a member of, I show a "Subscribe" button which should add themselves to the channel. Conversely, if they are a member of said channel then there is an "Unsubscribe" button which removes themselves from the channel.

To drive this logic to determine which button to show, I'm using channel.state.membership?.status. However, because I'm also using context to store the channel/thread (similar to this) between the Channel List and Channel Messages, then I need a way to reflect the membership change back to this context in order for the buttons to switch.

For example, this is what my subscribe action looks like:

const subscribe = async () => {
  await channel.addMembers([user.id]);

  // Fetch the latest channel data and state
  const [nextChannel] = await client.queryChannels({
    cid: channel.cid,
  });

  if (nextChannel) {
    // Update the context so that the channel new membership is reflected
    setChannel(nextChannel);
  }
}

It seems that React ignores the setChannel(nextChannel) call because it deems there to be no change between channel and nextChannel in this case (due to shallow comparison).

So what I've had to do is add a hack to force the screen to re-render by extending the context such that I can force a re-render:

setChannel(nextChannel);
// Update the same context as above
setForceUpdate((prev) => prev + 1);

Is there a recommended way to do this that I'm missing, without needing this force update workaround?

@khushal87
Copy link
Member

Hey @Liamandrew, can you try using our hook useChannelMembershipState for the same? This would give you real-time updates of the channel.state.membership. We use it to implement channel pinning/archiving on our side as well. Let us know if it was helpful. Thanks 😄

@Liamandrew
Copy link
Author

Hi @khushal87, thanks - Yes I've seen that hook and I am using it, but I think the problem is more basic than that. Currently I pass in the context channel like so:

const { channel, setChannel } = useChatContext();
const membership = useChannelMembershipState(channel);

Which is fine on the initial render. However, when the membership status is changed, I use setChannel(nextChannel) to attempt to re-render with the latest state but it seems this isn't enough to cause a re-rerender.

This is because React essentially performs the following check: Object.is(channel, nextChannel) and this is returning true, hence no re-render.

So my question is, what is the correct way to call setChannel to ensure React knows it's a new value and will re-render. Or, am I passing the wrong value into useChannelMembershipState

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