英文:
Firestore Subcollection Not Loading On Redux
问题
我在使用Redux Toolkit时遇到了一个问题,它没有更新Firestore DB子集的状态。Firebase身份验证字段正常工作,因为Redux会更新userId、firstName(displayName)和email字段,但来自Firestore的title和email字段未被更新。有什么想法吗?非常感谢!
请参见下面的代码示例:
// App.js
const dispatch = useDispatch();
useEffect(() => {
getAuth().onAuthStateChanged(async (user) => {
try {
const docRef = doc(db, "users", user.uid)
const docSnap = await getDoc(docRef)
if (user && docSnap.exists()) {
const data = docSnap.data()
console.log(user.uid, user.email, user.displayName, data.lastname, data.title)
console.log(data) // {lastname: 'sparrow', title: 'pirate'}
dispatch(loginUser({
userId: user.uid,
firstName: user.displayName,
lastName: data.lastname, //没有加载到Redux状态
title: data.title, //没有加载到Redux状态
email: user.email
}))
}
} catch (error) {
console.log(error.code)
}
})
})
// Redux
const initialState = {
userId: null,
firstName: null,
lastName: null,
title: null,
email: null,
}
const userSlice = createSlice({
name: "user",
initialState,
reducers: {
loginUser: (state, action) => {
state.userId = action.payload.userId
state.firstName = action.payload.firstName
state.lastName = action.payload.lastName
state.title = action.payload.title
state.email = action.payload.email
},
logoutUser: (state) => {
state.userId = null
state.firstName = null
state.lastName = null
state.title = null
state.email = null
},
}
})
export const { loginUser, logoutUser } = userSlice.actions
export default userSlice.reducer
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
这是你提供的代码的翻译。
英文:
I am having an issue with Redux Toolkit not updating it's state for Firestore DB Subcollections. The Firebase Authentication fields work as Redux does update the userId, firstName(displayName), and email fields however the title and email fields which are from Firestore are not being updated. Any thoughts? Greatly appreciate it!
Please see below:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
//App.js
const dispatch = useDispatch();
useEffect(() => {
getAuth().onAuthStateChanged(async (user) => {
try {
const docRef = doc(db, "users", user.uid)
const docSnap = await getDoc(docRef)
if (user && docSnap.exists()) {
const data = docSnap.data()
console.log(user.uid, user.email, user.displayName, data.lastname, data.title)
console.log(data) // {lastname: 'sparrow', title: 'pirate'}
dispatch(loginUser({
userId: user.uid,
firstName: user.displayName,
lastName: data.lastname, //not loading to redux state
title: data.title, // not loading to redux state
email: user.email
}))
}
} catch (error) {
console.log(error.code)
}
}
)})
//redux
const initialState = {
userId: null,
firstName: null,
lastName: null,
title: null,
email: null,
}
const userSlice = createSlice({
name: "user",
initialState,
reducers: {
loginUser: (state, action) => {
state.userId = action.payload.userId
state.firstName = action.payload.firstName
state.lastName = action.payload.lastName
state.title = action.payload.title
state.email = action.payload.email
},
logoutUser: (state) => {
state.userId = null
state.firstName = null
state.lastName = null
state.title = null
state.email = null
},
}
})
export const { loginUser, logoutUser } = userSlice.actions
export default userSlice.reducer
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<!-- end snippet -->
答案1
得分: 1
根据Redux Toolkit的创建Redux状态切片文档,您还需要将每个切片函数导出为userSlice.actions
,以及导出userSlice.reducer
,然后按照以下方式将切片reducer添加到存储:
features/user/userSlice.js
import {
createSlice
} from '@reduxjs/toolkit'
const initialState = {
userId: null,
firstName: null,
lastName: null,
title: null,
email: null,
}
const userSlice = createSlice({
name: "user",
initialState,
reducers: {
loginUser: (state, action) => {
const {
userId,
firstName,
lastName,
title,
email
} = action.payload;
return {
...state,
userId,
firstName,
lastName,
title,
email
};
},
logoutUser: (state) => {
state.userId = null
state.firstName = null
state.lastName = null
state.title = null
state.email = null
},
}
})
// Action creators are generated for each case reducer function
export const {
loginUser,
logoutUser
} = userSlice.actions
export default userSlice.reducer
app/store.js:
import { configureStore } from '@reduxjs/toolkit'
import userReducer from '../features/user/userSlice'
export const store = configureStore({
reducer: {
user: userReducer,
},
})
然后,在React组件中使用Redux状态和操作,就像您正在使用的方式一样。
正如您所说,您正在获取lastname
和title
的firestore数据,但为了确认,您还可以像这样发送它们,以防这些字段为空。
const loginUserAction = {
userId: user.uid,
firstName: user.displayName,
lastName: data.lastname || "", // ⇐ 👈
title: data.title || "", // ⇐ 👈
email: user.email
}
dispatch(loginUserAction)
更新:还要检查Redux Chrome扩展程序,以观察状态是否已更新。
英文:
According to the Create a Redux State Slice documentations from Redux Toolkit you also have to export each slice function as a userSlice.actions
along with userSlice.reducer
then Add the slice reducer to the store as follows :
features/user/userSlice.js
import {
createSlice
} from '@reduxjs/toolkit'
const initialState = {
userId: null,
firstName: null,
lastName: null,
title: null,
email: null,
}
const userSlice = createSlice({
name: "user",
initialState,
reducers: {
loginUser: (state, action) => {
const {
userId,
firstName,
lastName,
title,
email
} = action.payload;
return {
...state,
userId,
firstName,
lastName,
title,
email
};
},
logoutUser: (state) => {
state.userId = null
state.firstName = null
state.lastName = null
state.title = null
state.email = null
},
}
})
// Action creators are generated for each case reducer function
export const {
loginUser,
logoutUser
} = userSlice.actions
export default userSlice.reducer
app/store.js :
import { configureStore } from '@reduxjs/toolkit'
import userReducer from '../features/user/userSlice'
export const store = configureStore({
reducer: {
user: userReducer,
},
})
Then use the Redux State and Actions in React Components just how you are using it.
As you have said that you are getting firestore data of lastname
and title
as intended.
But just for confirming you can also send those like this so if in case those fields happen to be null.
const loginUserAction = {
userId: user.uid,
firstName: user.displayName,
lastName: data.lastname || "", // ⇐ 👈
title: data.title || "", // ⇐ 👈
email: user.email
}
dispatch(loginUserAction)
Update: Also check the Redux chrome extension to observe whether the states are updated or not.
Reference : Redux Toolkit Quick Start
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论