RTK recall api when set new state - react-native

I have a api with rtk (redux-toolkit) with a state 'search'
const [search, setSearch] = useState({nexToken: null})
const { data, isLoading, isError } = useGetPostQuery(search ?? skipToken)
useEffect(() => {
console.log('data', data)
}, [data])
When I call methods to add parameters to my search and set the new state does not happen again the api, why?
for example:
const addCity = () => {
const newFilter = { city: 'London. }
setSearch({...search, ...newFilter})
}

Related

Can't append reducer state in redux toolkit

I want to append the state.data with action.payload and i have tried everything it gives unidefined on .concat, .push or spreading in an array.
import { createAction, createReducer } from "#reduxjs/toolkit";
const initialState = {};
const request = createAction("allDataRequest");
const success = createAction("allDataSuccess");
const fail = createAction("allDataFailure");
const clear = createAction("clearErrors");
export const allServicesReducer = createReducer(initialState, (builder) => {
builder
.addCase(request, (state, action) => {
state.loading = true;
})
.addCase(success, (state, action) => {
state.loading = false;
state.data = action.payload;
// I want to append this state.data with payload
//state.data = state.data.concat(action.payload)
//state.data = [...state.data, ...action.payload]
// However i get stae.data undefined on both
})
.addCase(fail, (state, action) => {
state.loading = false;
state.error = action.payload;
})
.addCase(clear, (state, action) => {
state.error = null;
});
});
This is because your initial state does not have a .data field:
const initialState = {};
So, yes, it's going to be empty to begin with.
You need to either provide const initialState = {data: []} so there is a field, or update the reducer logic to handle the case where it doesn't exist.

How to use redux on a global functions

Iam currently working with a react-native project and wanted to use redux now what i want is that a global function that handles all firebase fetch data here is my globla function
connectFunctions.js
export const pullDataFromFirebaseSubCollection = async (collectionName, docId, subCollection, reducerName,) => {
const q = query(collection(db, collectionName,docId,subCollection));
const querySnapshot = await getDocs(q);
const documents = querySnapshot.docs.map((doc) => ({ key_id: doc.id, ...doc.data() }));
var redData = {
reducerName:reducerName,
data:documents
}
store.dispatch(middlewareDispatch(redData))//tried it inside the function does not work
return documents;
}
so on my App.js i imported then connectFunction.js and use pullDataFromFirebaseSubCollection
useEffect(()=>{
let isMounted = true; // note mutable flag
onAuthStateChanged(auth, (user) => {
if (user) {
console.log("user appjs", user);
dispatch(updateLoginStatus(true));
pullDataFromFirebaseSubCollection("Students","1","playlist","playlist").then((data)=>{
}).catch((err)=>{
console.log("logged error", err);
})
} else {
dispatch(updateLoginStatus(false))
}
_handleFinishLoading()
})
return () => { isMounted = false }
},[])
so on my library.js
i called store.getState().reducer.playlist the result is empty

React Native fecth data from firestore then dispatch not working-Dispatch empty array

I am trying to developp my 1st React Native app but I am bloqued with store/fetching data from firestore.
The problem is that is dispatch before fetching all data from firestore so my filteredProfiles array is empty and my flat list in my screen is so empty too.
what should I modify? If someone could help me, i will appreciate..Thanks!!
here is my code in my screen:
ProfilesListScreen.js
const ProfilesListScreen = props => {
const connectedUser = useSelector(state => state.profiles.user);
const filteredProfiles = useSelector(state => state.profiles.filteredProfiles)
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchProfiles());
}, [dispatch]);
My profilesAction.js in my store :
export const fetchProfiles= () => {
const loadedProfiles = [ ];
return async dispatch => {
await firebase.firestore().collection('users')
.get()
.then((profileSnapShot) => {
profileSnapShot.forEach((doc) => {
const firstname= doc.get("firstname");
const birth = doc.get("birth");
const age = getAge(birth.seconds);
const sex = doc.get("sex");
const newProfile= new profile(doc.id, firstname,age, "https://www.google.fr/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png");
loadedProfiles.push(newProfile);
});
})
dispatch({ type: SET_PROFILESLIST, profilesList: loadedProfiles } ) ;
};
and my reducer profiles.js
case SET_PROFILESLIST:
const newProfilesList = action.profilesList;
return {
filteredProfiles : newProfilesList,
};
Have a try by updating the code for fetchProfiles as below this might help you with your issue.
export const fetchProfiles= () => {
const loadedProfiles = [];
return async dispatch => {
const profileSnapShot = await firebase.firestore().collection('users').get()
profileSnapShot.forEach((doc) => {
const firstname= doc.get("firstname");
const birth = doc.get("birth");
const age = getAge(birth.seconds);
const sex = doc.get("sex");
const newProfile= new profile(doc.id, firstname,age, "https://www.google.fr/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png");
loadedProfiles.push(newProfile);
});
dispatch({ type: SET_PROFILESLIST, profilesList: loadedProfiles });
}
};

React Hook: Pass one value from custom react hook to another react custom hook?

I am trying to figure out how custom hooks are working. I want to get the person ID from one custom hook and pass the ID to a custom hook to get the user details. Is this working?
The user detail hook is always executed first and because of this it is not working.
App.js
const username = props.navigation.getParam('username');
const id = usePersonId('username');
const userInfo = useUserInfo(id);
usePersonId
export default (username) => {
const [personId, setPersonId] = useState(0);
useEffect(async () => {
let token = await new keys().getToken();
let x = await new userService().getPersonId(token, username);
setPersonId(x.user_id);
return () => {
console.log("cleaned up");
};
}, [])
return personId;
}
useUserInfo
export default (id) => {
const [userInfo, setUserInfo] = useState('');
useEffect(async () => {
let token = await new keys().getToken();
let x = await new userDetails().getUserInfo(token, id);
const info = {
"picture": pictureUrl,
};
setUserInfo(info);
return () => {
console.log("cleaned up");
};
}, [])
return userInfo;
Thanks,
Jan

How to outsource asyncData to Vuex Store?

I'm currently loading some data from firebase I wan't to be server side rendered so it can be indexed for SEO in asyncData on a page.
asyncData() {
return firebase.firestore().collection('Programms').get().then((querySnapshot) => {
const programms = [];
querySnapshot.forEach((doc) => {
const programm = doc.data();
programm.id = doc.id;
programms.push(programm)
})
return { programms: programms};
})
However I would like to convert this to my vuex store.
I know I could do this:
const actions = {
async nuxtServerInit({ commit }) {
firebase.firestore().collection('Programms').onSnapshot((querySnapshot) => {
const programms = [];
querySnapshot.forEach((doc) => {
const programm = doc.data();
programm.id = doc.id;
programms.push(programm)
})
console.log('loaded Programms', programms)
commit('setProgramms', programms);
})
},
}
But this way the data will be loaded for every route in my app. I wan't to load this data only in some pages where I also display it, so I don't load it unnecessary.
How could I do this in Vuex?
As #aldarund says, the fetch method is precisely what you want.
fetch ({ store, params }) {
return firebase.firestore().collection('Programms').get().then((querySnapshot) => {
const programms = [];
querySnapshot.forEach((doc) => {
const programm = doc.data();
programm.id = doc.id;
programms.push(programm)
})
.then(() => {
store.commit('setPrograms', programms)
})
}
See the docs here.