My problem here is I'm trying to collect the data in react hooks and then I want to pass it in my initial state of redux which can be shown like this:
import { createSlice } from '@reduxjs/toolkit'
import { doc, onSnapshot, setDoc } from 'firebase/firestore'
import { useState } from 'react'
import { useEffect } from 'react'
import { db } from '../lib/firebase'
import { itemsCollectionRef } from '../lib/firebase-collection'
function Items(params) {
const [UsersData,setUsersData] = useState([])
useEffect(() => {
const unsubscribe = onSnapshot(itemsCollectionRef,snapshot => {
setUsersData(snapshot.docs.map((doc,idx) => {
return {
...doc.data(),
name:doc.data().name
}
}))
})
return () => {
unsubscribe()
}
},[])
return UsersData
}
//Here I'm trying to pass all the data in firebase in the itemsSlice
export const itemsSlice = createSlice({
name:"items",
initialState:{ value: Items },
reducers:{
addItem: (state,action) => {
state.value.push(action.payload)
const { id,name,message,shape } = action.payload
setDoc(doc(db,`items`,`${action.payload.name}-${id}`),{
name:name,message:message,shape:shape
})
.then( res => {})
.catch(err => {})
},
...
}
})
So as you see I'm trying to pass my Usersdata
in the itemsSlice
but the thing is that my Items
function is passing all the format of code which is kind of wrong. It supposed to pass the array UsersData
what did I miss here? Can anyone help me? thanks :)
You will need to dispatch an action to populate theitems
state after the app/component has mounted and rendered and then run the useEffect
hook to make the asynchronous documents request. For this you'll need to provide valid initial state for the slice, and add a new case reducer to initialize the state to a specific value.
const initialState = { value: [] };
export const itemsSlice = createSlice({
name: "items",
initialState,
reducers: {
initialize: (_, action) => ({
state.value = action.payload;
}),
...
}
});
Next will be some useEffect
hook that makes the firebase call to get the documents and dispatches an action to initialize the items
state. The reason I say some useEffect
hook is because it seems Items
is defined like it's a custom hook, but it's not called like a React hook.
import { useDispatch } from 'react-redux';
import itemsSlice from '../items.slice';
...
const dispatch = useDispatch();
useEffect(() => {
const unsubscribe = onSnapshot(itemsCollectionRef, snapshot => {
const userData = snapshot.docs.map((doc, idx) => ({
...doc.data(),
name: doc.data().name
}));
dispatch(itemsSlice.initialize(userData));
});
return unsubscribe;
}, []);
The above logic could be abstracted into a custom hook and then imported and called from a React function component.