尝试获取具有特定日期值的第一个元素的标头

亚当·施瓦茨(Adam Schwarcz)

我正在尝试制作一个时间跟踪应用程序。我的问题是我试图在包含特定日期值的第一个元素上呈现“日期标头”。我正在使用Cloud Firestore。

我在考虑解决方案,其中我将能够基于日期将检索到的数组拆分为多个块,例如,2020年7月25日=将从那天开始一直进行分组,然后在该块的第一个元素上渲染标题。但是我不知道如何执行。

我将用屏幕截图进行解释。

我现在在哪里:

在此处输入图片说明

我要去的地方:

在此处输入图片说明

这是我在处理大多数Firestore事件的组件中的代码:

// Main Render
const Times = props => {
  // Handling the state
  const [hours, setHours] = useState(''); // Hours
  const [minutes, setMinutes] = useState(''); // Minutes
  const [description, setDescription] = useState(''); // Description
  const [entry, setEntry] = useState([]);
  const [isStopped, setIsStopped] = useState(true); // Lottie animation state
  const [loading, setLoading] = useState(true); // Loading state

  const time_entry = useEntries();

  // Update all inputs as you type
  const handleHoursChange = event => {
    setHours(event.target.value);
  };

  const handleMinutesChange = event => {
    setMinutes(event.target.value);
  };

  const handleDescriptionChange = event => {
    setDescription(event.target.value);
  };

  // Lottie: initial settings
  const defaultOptions = {
    loop: false,
    autoplay: false,
    animationData: animationData,
    rendererSettings: {
      preserveAspectRatio: 'xMidYMid slice'
    }
  };

  // Get entries on app load
  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then(response => response.json())
      .then(json => {
        setTimeout(() => setLoading(false), 1000);
      });
  }, []);

  // Load all documents from firebase collection on initial app load
  function useEntries() {
    useEffect(() => {
      firebase.db
        .collection('time_entries')
        .orderBy('createdOn.timestamp', 'desc')
        .onSnapshot(snapshot => {
          const newEntry = snapshot.docs.map(doc => ({
            id: doc.id,
            ...doc.data()
          }));

          setEntry(newEntry);
        });
    }, []);

    return entry;
  }

  // Date variable
  var date = new Date();

  // Send entry onSubmit
  function onSubmit(e) {
    e.preventDefault();

    // Perform lottie animation
    setIsStopped(false);
    setTimeout(() => setIsStopped(true), 400);

    firebase.db
      .collection('time_entries')
      .add({
        description,
        hours,
        minutes,
        createdOn: {
          date: date.toLocaleDateString(),
          time: date.toLocaleTimeString(),
          timestamp: date.toLocaleString()
        }
      })
      .then(() => {
        setDescription('');
        setHours('');
        setMinutes('');
      });
  }

  return (
    <section className="Times">
      <div style={{ maxWidth: props.width, width: '100%' }}>
        <form className="Form" onSubmit={onSubmit}>
          <div className="TimeInput">
            <TimeSelect
              variant="dropdown"
              unit="hours"
              value={hours}
              onChange={handleHoursChange}
            />
            <span>:</span>
            <TimeSelect
              variant="dropdown"
              unit="minutes"
              value={minutes}
              onChange={handleMinutesChange}
            />
          </div>
          <input
            className="TextInput"
            value={description}
            placeholder="What have you done?"
            onChange={handleDescriptionChange}
          />
          <div className="SubmitAnimation">
            <Lottie
              options={defaultOptions}
              height={100}
              width={100}
              isStopped={isStopped}
              speed={1.5}
            />
          </div>

          <ButtonBase className="Button" type="submit" focusRipple>
            <Check color="white" size={24} strokeWidth={3} />
          </ButtonBase>
        </form>

        <span className="ItemsHeader">
          <p2>Time entries</p2>
          <div className="TimeTotal">
            <Clock className="Icon" size={16} strokeWidth="3" />
            <p2>
              Total: <span>15h 30min</span>
            </p2>
          </div>
        </span>

        {time_entry.map(time_entry => (
          <>
            {loading ? (
              <>
                <FadeIn>
                  <Placeholder />
                </FadeIn>
              </>
            ) : (
              <FadeIn>
                <TimeItem
                  hours={time_entry.hours}
                  minutes={time_entry.minutes}
                  description={time_entry.description}
                  date={time_entry.createdOn.timestamp}
                  doc_id={time_entry.id}
                />
              </FadeIn>
            )}
          </>
        ))}
      </div>
    </section>
  );
};

export default Times;

firebase的屏幕截图(以更好地想象我如何构造数据):

在此处输入图片说明

卢克·斯托里

您想创建一个将日期映射到该日期的条目列表的集合对象-您可以使用simple来实现reduce,我将在下面提供它。

const testData = [
  { id: "1", time: '2020-07-24T02:00:00.000Z'},
  { id: "2", time: '2020-07-25T15:00:00.000Z'},
  { id: "3", time: '2020-05-24T12:00:00.000Z'},
  { id: "4", time: '2020-06-24T17:00:00.000Z'},
  { id: "5", time: '2020-07-25T04:00:00.000Z'},
  { id: "6", time: '2020-07-15T19:00:00.000Z'},
  { id: "7", time: '2020-07-15T23:00:00.000Z'},
];

const splitIntoDays = (entries) => entries.reduce((collection, entry) => {
  const date = new Date(entry.time).toDateString()
  collection[date] = [...(collection[date] || []), entry]
  return collection;
}, {})


console.log(splitIntoDays(testData));

然后,您可以在自己的内部使用此方法onSnapshot来将状态设置为此精简对象。useEffect需要位于组件的根目录上,该组件将在挂载后运行一次,获取并订阅Firestore。不要从中返回任何内容,只需设置状态即可。

setEntriesSplitByDate(splitIntoDays(newEntries));

然后,在稍后的render方法中,keys从该对象中提取(将是日期字符串),在标题(h2)中显示日期字符串,并创建第二个嵌套映射,该映射映射该块列表中的条目,从而呈现一个Entry每件。

    <section>
      {Object.keys(entriesSplitByDate).map(dateKey => (
        <div key={dateKey}>
          <h2>{dateKey}</h2>
          {entriesSplitByDate[dateKey].map(entry => (
            <EntryItem entry={entry} />
          ))}
        </div>
      ))}
    </section>

工作演示沙箱

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

mysql查询获取两个日期之间的第一个特定日期

来自分类Dev

如何通过jQuery在HTML中获取具有特定类的第一个元素的ID值

来自分类Dev

从具有特定类的第一个输入中获取父表单元素

来自分类Dev

从具有特定类的第一个输入中获取父表单元素

来自分类Dev

查找具有匹配日期分量的第一个日期时间元素的索引

来自分类Dev

将数据堆叠到具有两个标头的行中,并且第一个标头不合并

来自分类Dev

计算具有给定日期中第一个出现的相关记录的记录

来自分类Dev

如何将熊猫数据框的第一个标头转换为具有相同ID的行

来自分类Dev

在特定日期后的下周一获得第一个?

来自分类Dev

我如何找到特定成员具有特定值的第一个结构?

来自分类Dev

如何选择具有特定类别的第一个元素

来自分类Dev

选择元素后具有特定类别的第一个兄弟姐妹

来自分类Dev

如果有任何重复,则选择具有特定属性的第一个元素,否则选择第一个元素

来自分类Dev

如何检索向量中第一个找到的具有最低值的元素

来自分类Dev

如何获得第一个标头孩子?

来自分类Dev

如何获得第一个标头孩子?

来自分类Dev

给定日期范围内的第一个非空值

来自分类Dev

查找具有特定属性值的第一个节点

来自分类Dev

从字符串获取具有随机数字的第一个值

来自分类Dev

在 CSS 中选择具有特定类的序列的第一个和最后一个元素

来自分类Dev

在一行中查找具有特定值的第一个和最后一个条目

来自分类Dev

Scala - Spark - 如何获取具有数据框列的不同值和此不同值的第一个日期的新数据框?

来自分类Dev

检查除第一个元素外的所有元素是否都具有特定类

来自分类Dev

检查最后一个(或第一个)节点的子节点是否具有特定值

来自分类Dev

jQuery查找父元素以查找具有特定数据的第一个元素

来自分类Dev

MySQL查询以获取具有日期字段的第一个月的最后一天的行

来自分类Dev

获取第一个匹配的元素,如果没有匹配项,则获取第一个?

来自分类Dev

如何查看数组的一部分,获取特定值的第一个元素

来自分类Dev

php在特定日期后的第一个星期一作为字符串

Related 相关文章

  1. 1

    mysql查询获取两个日期之间的第一个特定日期

  2. 2

    如何通过jQuery在HTML中获取具有特定类的第一个元素的ID值

  3. 3

    从具有特定类的第一个输入中获取父表单元素

  4. 4

    从具有特定类的第一个输入中获取父表单元素

  5. 5

    查找具有匹配日期分量的第一个日期时间元素的索引

  6. 6

    将数据堆叠到具有两个标头的行中,并且第一个标头不合并

  7. 7

    计算具有给定日期中第一个出现的相关记录的记录

  8. 8

    如何将熊猫数据框的第一个标头转换为具有相同ID的行

  9. 9

    在特定日期后的下周一获得第一个?

  10. 10

    我如何找到特定成员具有特定值的第一个结构?

  11. 11

    如何选择具有特定类别的第一个元素

  12. 12

    选择元素后具有特定类别的第一个兄弟姐妹

  13. 13

    如果有任何重复,则选择具有特定属性的第一个元素,否则选择第一个元素

  14. 14

    如何检索向量中第一个找到的具有最低值的元素

  15. 15

    如何获得第一个标头孩子?

  16. 16

    如何获得第一个标头孩子?

  17. 17

    给定日期范围内的第一个非空值

  18. 18

    查找具有特定属性值的第一个节点

  19. 19

    从字符串获取具有随机数字的第一个值

  20. 20

    在 CSS 中选择具有特定类的序列的第一个和最后一个元素

  21. 21

    在一行中查找具有特定值的第一个和最后一个条目

  22. 22

    Scala - Spark - 如何获取具有数据框列的不同值和此不同值的第一个日期的新数据框?

  23. 23

    检查除第一个元素外的所有元素是否都具有特定类

  24. 24

    检查最后一个(或第一个)节点的子节点是否具有特定值

  25. 25

    jQuery查找父元素以查找具有特定数据的第一个元素

  26. 26

    MySQL查询以获取具有日期字段的第一个月的最后一天的行

  27. 27

    获取第一个匹配的元素,如果没有匹配项,则获取第一个?

  28. 28

    如何查看数组的一部分,获取特定值的第一个元素

  29. 29

    php在特定日期后的第一个星期一作为字符串

热门标签

归档