如何使用Firebase / Firestore将componentDidMound和componentWillUnmount转换为UseEffect(反应挂钩)?

时间:2020-04-30 14:47:48

标签: reactjs firebase

在使用Firebase时,如何使用useEffect挂钩同时替换componentDidMount和componentWillUnmount?我找不到此“退订”功能的解决方案。

unsubscribe = null;

componentDidMount = async () => {
  this.unsubscribe = firestore.collection('posts').onSnapshot(snapshot => {
    const posts = snapshot.docs.map(...)
    this.setState({ posts })
  })
}

componentWillUnmount = () => {
  this.unsubscribe()
}

这是我尝试过的:

useEffect(() => {
  async function getSnapshot() {
  const unsubscribe = firestore.collection('posts').onSnapshot(snapshot => {
        const posts = snapshot.docs.map(...)
        setPosts(posts)
  }
  getSnapshot()
  //return something to clear it? I don't have access to 'unsubscribe'
}, [])

2 个答案:

答案 0 :(得分:1)

在useEffect中使用异步可能会遇到麻烦,请查看https://www.npmjs.com/package/use-async-effect

useAsyncEffect( async() => {
   const unsubscribe = await firestore.collection('posts').onSnapshot(snapshot => {
       const posts = snapshot.docs.map(...)
       setPosts(posts)
    }
    return () => {
      console.log("unmount")
      unsubscribe()
    };
}, [])

编辑:实际上,从文档看来,您根本不需要异步: 您尝试过这种格式吗?

  useEffect(
    () => {
      const unsubscribe = firebase
        .firestore()
        .collection('recipes')
        .doc(id)
        .collection('ingredients')
        .onSnapshot( snapshot => { const ingredients = [] snapshot.forEach(doc => { ingredients.push(doc) }) setLoading(false) setIngredients(ingredients) }, err => { setError(err) } )

      return () => unsubscribe()
    },
    [id]
  )

答案 1 :(得分:1)

您实际上与答案很接近。您没有在函数中使用等待,因此没有必要使用它。

useEffect(() => {
  const unsubscribe = firestore.collection('posts').onSnapshot((snapshot) => {
    const posts = snapshot.docs.map(...)
    setPosts(posts);
  });
  return () => {
    unsubscribe();
  };
}, []);

如果您确实需要使用异步功能,则可以利用闭包取消订阅异步功能。

useEffect(() => {
  let unsubscribe;
  async function getSnapshot() {
    unsubscribe = firestore.collection('posts').onSnapshot((snapshot) => {
      const posts = snapshot.docs.map(...)
      setPosts(posts);
    });
  }
  getSnapshot();
  return () => {
    unsubscribe();
  };
}, []);