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

Non-listening hooks can cancel other listeners #135

Open
jckw opened this issue Oct 12, 2021 · 0 comments
Open

Non-listening hooks can cancel other listeners #135

jckw opened this issue Oct 12, 2021 · 0 comments

Comments

@jckw
Copy link
Contributor

jckw commented Oct 12, 2021

Thanks again for this library, it's been a great help in getting firebase to behave in our application.

I came across a bug related to having multiple useCollection hooks on the same collection.

The summary is: it appears that if one hook listens (i.e. passes { listen: true }) and another doesn't, but is called later, then the the first listener breaks.

I've put together a demo repo here that illustrates the problem: https://github.com/jckw/swr-firestore-listen-bug

It seems that we either need to commit to listening, or not, for a particular collection otherwise we risk having listening and non-listening hook calls which can lead to unexpected results.

const Main = () => {
  const { data, add } = useCollection<Note>("notes", { listen: true })

  const [newNote, setNewNote] = useState("")
  const submitNewNote = () => {
    console.log("Adding", newNote)
    add({ content: newNote })
    setNewNote("")

    /**
     * Notes on the effect: since the NonListenList doesn't listen to the collection,
     * neither will update when we trigger this. Interestingly, if you make a change and
     * the code updates with live reloading, then the listener works again.
     */
  }

  return (
    <div>
      <div>swr-firestore listening bug demo</div>

      <hr />
      <p>Listening</p>
      <div>
        {data?.map((n, i) => (
          <div key={i}>{n.content}</div>
        ))}
      </div>
      <hr />
      <p>Non-listening</p>
      <NonListenList />
      <hr />

      <div>
        <form
          onSubmit={(e) => {
            e.preventDefault()
            submitNewNote()
          }}
        >
          <input
            type="text"
            value={newNote}
            onChange={(e) => setNewNote(e.target.value)}
          />
          <button type="submit">Add note</button>
        </form>
      </div>
    </div>
  )
}
const NonListenList = () => {
  const { data } = useCollection<Note>("notes")
  // Adding a listener here makes the other listener work too
  // const { data } = useCollection<Note>("notes", { listen: true })

  return (
    <div>
      {data?.map((n, i) => (
        <div key={i}>{n.content}</div>
      ))}
    </div>
  )
}

export default NonListenList
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

1 participant