Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/469.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 尝试在第一个元素上获取值为specific date的标头_Javascript_Reactjs_Google Cloud Firestore - Fatal编程技术网

Javascript 尝试在第一个元素上获取值为specific date的标头

Javascript 尝试在第一个元素上获取值为specific date的标头,javascript,reactjs,google-cloud-firestore,Javascript,Reactjs,Google Cloud Firestore,我正在尝试制作一个时间跟踪应用程序。我的问题是,我试图在包含特定日期值的第一个元素上呈现“日期头”。我正在使用CloudFireStore 我正在考虑一种解决方案,可以根据日期将检索到的数组拆分为块,这意味着,例如,25/07/2020=将从那天开始的所有时间分组,然后在该块的第一个元素上呈现一个标题。但我不知道该怎么做 我会用截图来解释 我现在的处境: 我想得到的是: 这是我在处理大多数firestore事件的组件中的代码: // Main Render const Times = pro

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

我正在考虑一种解决方案,可以根据日期将检索到的数组拆分为块,这意味着,例如,25/07/2020=将从那天开始的所有时间分组,然后在该块的第一个元素上呈现一个标题。但我不知道该怎么做

我会用截图来解释

我现在的处境:

我想得到的是:

这是我在处理大多数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;
//主渲染
常量时间=道具=>{
//治理国家
const[hours,setHours]=useState(“”);//小时
const[minutes,setMinutes]=useState(“”);//分钟
const[description,setDescription]=useState(“”);//description
const[entry,setEntry]=useState([]);
const[isStopped,setIsStopped]=useState(true);//乐蒂动画状态
const[loading,setLoading]=useState(true);//加载状态
const time_entry=useEntries();
//键入时更新所有输入
const handleHoursChange=事件=>{
设置小时数(事件目标值);
};
const handleMinutesChange=事件=>{
setMinutes(event.target.value);
};
const handleDescriptionChange=事件=>{
setDescription(事件、目标、值);
};
//洛蒂:初始设置
const defaultOptions={
循环:false,
自动播放:错误,
animationData:animationData,
渲染器设置:{
PreserveSpectratio:'xMidYMid slice'
}
};
//在应用程序加载时获取条目
useffect(()=>{
取('https://jsonplaceholder.typicode.com/posts')
.then(response=>response.json())
。然后(json=>{
setTimeout(()=>setLoading(false),1000);
});
}, []);
//在初始应用程序加载时加载firebase集合中的所有文档
函数useEntries(){
useffect(()=>{
firebase.db
.collection('time\u entries')
.orderBy('createdOn.timestamp','desc')
.onSnapshot(快照=>{
const newEntry=snapshot.docs.map(doc=>({
id:doc.id,
…文件数据()
}));
setEntry(newEntry);
});
}, []);
返回条目;
}
//日期变量
变量日期=新日期();
//在提交时发送条目
提交函数(e){
e、 预防默认值();
//表演乐蒂动画
setIsStopped(假);
setTimeout(()=>setIsStopped(true),400);
firebase.db
.collection('time\u entries')
.添加({
描述
小时,
会议记录,
createdOn:{
日期:date.toLocaleDateString(),
时间:date.toLocaleTimeString(),
时间戳:date.toLocaleString()
}
})
.然后(()=>{
setDescription(“”);
设定时间(“”);
设置分钟(“”);
});
}
返回(
:
时间条目
总计:15小时30分钟
{time\u entry.map(time\u entry=>(
{加载(
) : (
)}
))}
);
};
导出默认时间;
firebase的屏幕截图(以便更好地想象我是如何构建数据的):


您想创建一个集合对象,将日期映射到该日期的条目列表-您可以使用下面提供的一个简单的
reduce

const testData=[
{id:“1”,时间:'2020-07-24T02:00:00.000Z'},
{id:“2”,时间:'2020-07-25T15:00:00.000Z'},
{id:“3”,时间:'2020-05-24T12:00:00.000Z'},
{id:“4”,时间:'2020-06-24T17:00:00.000Z'},
{id:“5”,时间:'2020-07-25T04:00:00.000Z'},
{id:“6”,时间:'2020-07-15T19:00:00.000Z'},
{id:“7”,时间:'2020-07-15T23:00:00.000Z'},
];
const splitintodies=(条目)=>entries.reduce((集合,条目)=>{
const date=新日期(entry.time).toDateString()
收款[日期]=[…(收款[日期]| |[]),分录]
回收;
}, {})

log(拆分为天(testData))
您想创建一个集合对象,将日期映射到该日期的条目列表-您可以使用我在下面提供的一个简单的
reduce
来实现这一点

const testData=[
{id:“1”,时间:'2020-07-24T02:00:00.000Z'},
{id:“2”,时间:'2020-07-25T15:00:00.000Z'},
{id:“3”,时间:'2020-05-24T12:00:00.000Z'},
{id:“4”,时间:'2020-06-24T17:00:00.000Z'},
{id:“5”,时间:'2020-07-25T04:00:00.000Z'},
{id:“6”,时间:'2020-07-15T19:00:00.000Z'},
{id:“7”,时间:'2020-07-15T23:00:00.000Z'},
];
const splitintodies=(条目)=>entries.reduce((集合,条目)=>{
const date=新日期(entry.time).toDateString()
收款[日期]=[…(收款[日期]| |[]),分录]
回收;
}, {})

log(拆分为天(testData))Yeees!非常感谢。我已经解决了第一部分,我需要按日期将数据划分成块。遗憾的是,我现在对映射部分的理解还不够。因此,
map
基本上遍历了这些块并为它们做了一些事情,在本例中返回一个div,我理解映射本身的概念。我只是在将您的示例移植到我的用例中时遇到了一个问题。具体来说,我不知道我应该放什么来代替DateToEntries对象,它应该是reduce的结果。根据您存储状态的方式,您可能可以在
返回之前计算它