首页 > 解决方案 > 使用 React useState 扩展运算符 // 从 Firebase 填充状态

问题描述

我正在从 Firebase 检索一些数据,这些数据返回两个我想在本地状态下存储为数组的对象。我正在尝试使用扩展运算符来维护当前状态并附加新记录,但它似乎一直在覆盖原始记录?

下面的代码从 firebase 返回两个对象,但我只能看到状态中设置的最后一个对象。

const [date, setDate] = useState(new Date(new Date().setHours(0, 0, 0, 0))); //setting initial state to current day midnight
    const [step, setStep] = useState(0); // Count the days ahead the user is trying to book.
    const [alert, setAlert] = useState(false); // Alert when trying to exceed booking window.
    const [bookings, setBookings] = useState([]);

    const bookingWindowAllowed = 7; // Used to limit the forward bookings (evaluated vs state.step)

    useEffect(() => {
        setLoading(true);
        setBookings([]);

        //date as firestore timestamp
        const setDate = firebase.firestore.Timestamp.fromMillis(
            dayjs(date).valueOf()
        );
        //Compute tomorrow as firestore timestamp
        const futureDate = firebase.firestore.Timestamp.fromMillis(
            dayjs(date).add(1, 'day').valueOf()
        );

        // Get bookings from firestore
        firestore
            .collection('bookings')
            .where('studio.ID', '==', 'kM8p1jSenI4M0Mr1PzBo')
            .where('startTime', '>=', setDate)
            .where('startTime', '<', futureDate)
            .get()
            .then((querySnapshot) => {
                querySnapshot.forEach((doc) => {
                    console.log(doc.data());
                    setBookings([...bookings, doc.data()]);
                });
                setLoading(false);
            })
            .catch((error) => {
                console.log('Error getting documents: ', error);
                setLoading(false);
            });
    }, [date]);

标签: reactjsfirebasegoogle-cloud-firestore

解决方案


ReactsetState函数是异步的,这意味着它们不会立即更改状态,这就是为什么像您正在实现的模式不能按预期工作的原因。

最好将这两个对象保存在一个数组中,在迭代之后,将该数组保存为状态:

useEffect(() => {
    setLoading(true);
    setBookings([]);

    //date as firestore timestamp
    const setDate = firebase.firestore.Timestamp.fromMillis(
        dayjs(date).valueOf()
    );
    //Compute tomorrow as firestore timestamp
    const futureDate = firebase.firestore.Timestamp.fromMillis(
        dayjs(date).add(1, 'day').valueOf()
    );
    // Get bookings from firestore
    firestore
        .collection('bookings')
        .where('studio.ID', '==', 'kM8p1jSenI4M0Mr1PzBo')
        .where('startTime', '>=', setDate)
        .where('startTime', '<', futureDate)
        .get()
        .then((querySnapshot) => {

            const newBookings=[]    /// create an empty array

            querySnapshot.forEach((doc) => {
                console.log(doc.data());
                newBookings.push(doc.data()); // push each object to newBookings
            });
            setBookings(newBookings); // save it in state
            setLoading(false);
        })
        .catch((error) => {
            console.log('Error getting documents: ', error);
            setLoading(false);
        });
}, [date]);

推荐阅读