【问题标题】:Re-rendering a react component after data is added to my firebase firestore back end database将数据添加到我的 firebase firestore 后端数据库后重新渲染反应组件
【发布时间】:2021-07-30 13:24:19
【问题描述】:

我有一个 react native 组件,它根据我的 firestore 数据库中有多少显示任务列表。它们最初在页面第一次渲染时被渲染。

用户可以添加任务,并且我希望在将新任务添加/更新到 firestore 数据库后,屏幕上的组件能够在屏幕上重新显示。任务是从我数据库中的任务集合中呈现的。

Firesstore Firebase 结构:

users(collection)-->tasks(collection)-->taskdata(document)

从后端请求任务并将其设置为它们所在类组件的本地状态。

constructor(props) {

        this.state = {

            tasks_: []
           
        }
}

在数据库的快照请求下获取给定用户 ID 的任务并将它们设置为本地状态。

getInfoHandler() {
        
          var docRefTest = 
            db.collection('users').doc(this.state.id).collection('tasks').get()
             .then(querySnapshot => {

              const documents = querySnapshot.docs.map(doc => doc.data());
              
              this.setState({ tasks_: documents });
        });

组件从本地状态检索任务并将它们呈现在页面上。根据存储在后端数据库中的任务映射它们。

在页面渲染时通过组件调用 getInfoHandler() 函数获取任务。

我希望每次自动添加任务时都呈现一个新组件。

export default class Tasks extends React.Component {

getInfoHandler() {

          var docRefTest = 
            db.collection('users').doc(this.state.id).collection('tasks').get()
             .then(querySnapshot => {

              const documents = querySnapshot.docs.map(doc => doc.data());

              this.setState({ tasks_: documents });
});

componentDidMount () {

   this.getInfoHandler();

}

render() {

        const tasks1 = this.state.tasks;

        return (
            <View style={styles.tasks}>
                        {tasks1.map((task) => {
                            return (
                                <TaskItem
                                    notes={task.notes}
                                    reminder={task.reminder}
                                    name={task.name}
                                    assigned={task.assigned}
                                
                                />
                            );
                        })}
                    </View>
                    
         )
     }
}

addTaskHandler() 用于将任务添加到后端。它位于不同的模态组件中,并在按钮提交和关闭模态时激活

addTaskHandler () {
 db.collection('users').doc(this.state.id).collection('tasks').doc().set({
            name: this.state.name,
            assigned: this.state.assigned,
            tag: this.state.tag
        })
    }

【问题讨论】:

  • 添加新任务的代码在哪里?
  • 它在页面上弹出的另一个模态组件中我可以编辑问题并添加它。
  • 据我了解,您希望在 Firestore 之后本地呈现该新任务。所以你也可以分享那个代码?
  • 是的,页面已打开,并且已经存在的任务出现......但如果用户向数据库添加新任务,我希望它出现在页面上,而无需手动刷新页面。
  • 我想我可能需要使用 snapshot() 或 componentDidUpdate() 吗?

标签: reactjs react-native google-cloud-firestore addeventlistener


【解决方案1】:

您需要结合使用useStateuseEffectonSnapshot()(一个监听器)。在不提供所有细节的情况下(部分是因为我的代码具有“包装”函数层),它希望像这样的功能组件和钩子(强烈推荐超过组件类):

export default function ShowThese(props) {
  const {id} = props;

  const [tasks_, setTasks_] = useState([]);

  useEffect(() => {
    return db
      .collection('users')
      .doc(id)
      .collection('tasks')
      .onSnapshot(
        (querySnapshot) => {
        // returns a promise
        if (!querySnapshot.empty) {
          // DataFromSnapshot is what ever code you use to get an array of data from
          // a querySnapshot   
          let dataArray = DataFromSnapshot(querySnapshot);
          setTasks_(dataArray);
        } else //whatever you choose to do when there are no records;
      },
      (err) => {
        //whatever you want to do in case of an error
      }
    );
  }, [id]); //

  return //whatever you choose to render;
}

几个注意事项:

.onSnapshot 返回一个取消订阅函数useEffect() 将在您的组件卸载时自动调用该函数 - 减少内存泄漏。如果id 发生变化,则有点依赖组件卸载/重新安装。

每次查询中的数据发生变化时,如果成功则调用(querySnapshot) =&gt;{ 函数(从而更新tasks_),并在出错时调用(err) =&gt;{ 函数。

【讨论】:

  • 是的,出于这个原因,我正在考虑切换到功能组件……使用 useEffect 和 useState。我将这样做并尝试您上面推荐的方法!
猜你喜欢
  • 1970-01-01
  • 2021-07-11
  • 1970-01-01
  • 1970-01-01
  • 2020-10-02
  • 2021-06-23
  • 1970-01-01
  • 2020-01-13
  • 2022-07-08
相关资源
最近更新 更多