【问题标题】:FireStore - Update the UI with new data without reloading the browserFireStore - 使用新数据更新 UI 而无需重新加载浏览器
【发布时间】:2020-06-24 22:20:41
【问题描述】:

我使用以下组件在 Google Cloud FireStore 集合中添加新数据:

import React, { useState } from 'react';
import { db } from '../firebase';

const AddCard = ({ totalDoclNumbers }) => {
  const [newOriginalText, setNewOriginalText] = useState([]);
  const [newTranslatedText, setNewTranslatedText] = useState([]);
  const nextNumber = totalDoclNumbers + 1;

  const onAdd = async () => {
    await db.collection('FlashCards').add({
      originalText: newOriginalText,
      translatedText: newTranslatedText,
      customId: Number(nextNumber),
    });
  };

  return (
    <ul>
      <li key={nextNumber}>
        <input
          type='text'
          readOnly
          defaultValue={nextNumber}
        />
        <div>
            <textarea
              placeholder='English'
              onChange={(e) => setNewOriginalText(e.target.value)}
            />
        </div>
        <textarea
          placeholder='Translation'
          onChange={(e) => setNewTranslatedText(e.target.value)}
        />
        <button onClick={onAdd}>
          Add
        </button>
      </li>
    </ul>
  );
};

导出默认的AddCard;

添加按钮有效,我可以看到新数据已添加到 Google 服务器上的集合中,但是为了能够看到这些新数据,我必须刷新页面。

为了解决这个问题,我决定使用 onSnapshot 函数如下:

import React, { useState } from 'react';
import { db } from '../firebase';

const AddCard = ({ totalDoclNumbers }) => {
  const [newOriginalText, setNewOriginalText] = useState([]);
  const [newTranslatedText, setNewTranslatedText] = useState([]);
  const nextNumber = totalDoclNumbers + 1;

  const onAdd = async () => {
    await db.collection('FlashCards').add({
      originalText: newOriginalText,
      translatedText: newTranslatedText,
      customId: Number(nextNumber),
    });
  };

  const renderDocList = () => {
    return (
      <ul>
        <li key={nextNumber}>
          <input
            type='text'
            defaultValue={nextNumber}
          />
          <div>
              <textarea
                placeholder='English'
                onChange={(e) => setNewOriginalText(e.target.value)}
              />
          </div>
          <textarea
            placeholder='Translation'
            onChange={(e) => setNewTranslatedText(e.target.value)}
          />
          <button onClick={onAdd}>
            Add
          </button>
        </li>
      </ul>
    );
  };

  db.collection('FlashCards').onSnapshot((snapshot) => {
    let changes = snapshot.docChanges();
    changes.forEach((change) => {
      if (change.type === 'added') {
        renderDocList();
      }
    });
  });

  return <>{renderDocList()}</>;
};

export default AddCard;

虽然新数据已添加到 FireStore 集合中,但我在页面上看不到任何更改。我仍然必须刷新(重新加载)浏览器才能看到这些更改。 我做错了什么?

【问题讨论】:

    标签: reactjs google-cloud-firestore react-hooks


    【解决方案1】:

    我会以不同的方式处理它 - 为什么要上传然后再次加载?

    当 onAdd 被调用保存你的数据来设置状态时,状态的改变会用新的数据重新渲染你的组件。

    如果您坚持使用 save\load 路径,请尝试使用 use effect hook 与 set state 相结合,如下所述: https://dev.to/chantastic/connect-useeffect-and-usestate-to-update-components-with-data-4aaj

    React.js 的很多功能都处于状态,使用它:)

    【讨论】:

      【解决方案2】:

      没有人会在这个 sn-p 中看到 renderDocList 调用的结果:

      db.collection('FlashCards').onSnapshot((snapshot) => {
        let changes = snapshot.docChanges();
        changes.forEach((change) => {
          if (change.type === 'added') {
            renderDocList();
          }
        });
      });
      

      如果你想要更新 UI,你需要告诉 React 有新数据要渲染。这就是 useState 钩子的用途。它不能完全了解您的代码如何影响正在呈现的内容,但您需要调用一个 setter 来修改组件呈现的状态。

      假设您的原始文本来自数据库,您会这样做:

      db.collection('FlashCards').onSnapshot((snapshot) => {
        let changes = snapshot.docChanges();
        changes.forEach((change) => {
          if (change.type === 'added') {
            setNewOriginalText("new document added");
          }
        });
      });
      

      这反过来又会重新渲染任何显示原始文本的组件。

      另见:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-04-25
        • 2018-05-26
        • 1970-01-01
        • 2012-05-19
        • 2010-12-15
        • 2012-04-27
        • 2021-11-29
        相关资源
        最近更新 更多